1 /* $OpenBSD: igc_i225.c,v 1.1 2021/10/31 14:52:57 patrick Exp $ */ 2 /*- 3 * Copyright 2021 Intel Corp 4 * Copyright 2021 Rubicon Communications, LLC (Netgate) 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <dev/pci/igc_api.h> 9 10 int igc_init_nvm_params_i225(struct igc_hw *); 11 int igc_init_mac_params_i225(struct igc_hw *); 12 int igc_init_phy_params_i225(struct igc_hw *); 13 int igc_reset_hw_i225(struct igc_hw *); 14 int igc_acquire_nvm_i225(struct igc_hw *); 15 void igc_release_nvm_i225(struct igc_hw *); 16 int igc_get_hw_semaphore_i225(struct igc_hw *); 17 int __igc_write_nvm_srwr(struct igc_hw *, uint16_t, uint16_t, uint16_t *); 18 int igc_pool_flash_update_done_i225(struct igc_hw *); 19 20 /** 21 * igc_init_nvm_params_i225 - Init NVM func ptrs. 22 * @hw: pointer to the HW structure 23 **/ 24 int 25 igc_init_nvm_params_i225(struct igc_hw *hw) 26 { 27 struct igc_nvm_info *nvm = &hw->nvm; 28 uint32_t eecd = IGC_READ_REG(hw, IGC_EECD); 29 uint16_t size; 30 31 DEBUGFUNC("igc_init_nvm_params_i225"); 32 33 size = (uint16_t)((eecd & IGC_EECD_SIZE_EX_MASK) >> 34 IGC_EECD_SIZE_EX_SHIFT); 35 /* 36 * Added to a constant, "size" becomes the left-shift value 37 * for setting word_size. 38 */ 39 size += NVM_WORD_SIZE_BASE_SHIFT; 40 41 /* Just in case size is out of range, cap it to the largest 42 * EEPROM size supported. 43 */ 44 if (size > 15) 45 size = 15; 46 47 nvm->word_size = 1 << size; 48 nvm->opcode_bits = 8; 49 nvm->delay_usec = 1; 50 nvm->type = igc_nvm_eeprom_spi; 51 52 nvm->page_size = eecd & IGC_EECD_ADDR_BITS ? 32 : 8; 53 nvm->address_bits = eecd & IGC_EECD_ADDR_BITS ? 16 : 8; 54 55 if (nvm->word_size == (1 << 15)) 56 nvm->page_size = 128; 57 58 nvm->ops.acquire = igc_acquire_nvm_i225; 59 nvm->ops.release = igc_release_nvm_i225; 60 if (igc_get_flash_presence_i225(hw)) { 61 hw->nvm.type = igc_nvm_flash_hw; 62 nvm->ops.read = igc_read_nvm_srrd_i225; 63 nvm->ops.write = igc_write_nvm_srwr_i225; 64 nvm->ops.validate = igc_validate_nvm_checksum_i225; 65 nvm->ops.update = igc_update_nvm_checksum_i225; 66 } else { 67 hw->nvm.type = igc_nvm_invm; 68 nvm->ops.write = igc_null_write_nvm; 69 nvm->ops.validate = igc_null_ops_generic; 70 nvm->ops.update = igc_null_ops_generic; 71 } 72 73 return IGC_SUCCESS; 74 } 75 76 /** 77 * igc_init_mac_params_i225 - Init MAC func ptrs. 78 * @hw: pointer to the HW structure 79 **/ 80 int 81 igc_init_mac_params_i225(struct igc_hw *hw) 82 { 83 struct igc_mac_info *mac = &hw->mac; 84 struct igc_dev_spec_i225 *dev_spec = &hw->dev_spec._i225; 85 86 DEBUGFUNC("igc_init_mac_params_i225"); 87 88 /* Initialize function pointer */ 89 igc_init_mac_ops_generic(hw); 90 91 /* Set media type */ 92 hw->phy.media_type = igc_media_type_copper; 93 /* Set mta register count */ 94 mac->mta_reg_count = 128; 95 /* Set rar entry count */ 96 mac->rar_entry_count = IGC_RAR_ENTRIES_BASE; 97 98 /* reset */ 99 mac->ops.reset_hw = igc_reset_hw_i225; 100 /* hw initialization */ 101 mac->ops.init_hw = igc_init_hw_i225; 102 /* link setup */ 103 mac->ops.setup_link = igc_setup_link_generic; 104 /* check for link */ 105 mac->ops.check_for_link = igc_check_for_link_i225; 106 /* link info */ 107 mac->ops.get_link_up_info = igc_get_speed_and_duplex_copper_generic; 108 /* acquire SW_FW sync */ 109 mac->ops.acquire_swfw_sync = igc_acquire_swfw_sync_i225; 110 /* release SW_FW sync */ 111 mac->ops.release_swfw_sync = igc_release_swfw_sync_i225; 112 113 /* Allow a single clear of the SW semaphore on I225 */ 114 dev_spec->clear_semaphore_once = true; 115 mac->ops.setup_physical_interface = igc_setup_copper_link_i225; 116 117 /* Set if part includes ASF firmware */ 118 mac->asf_firmware_present = true; 119 120 /* multicast address update */ 121 mac->ops.update_mc_addr_list = igc_update_mc_addr_list_generic; 122 123 mac->ops.write_vfta = igc_write_vfta_generic; 124 125 return IGC_SUCCESS; 126 } 127 128 /** 129 * igc_init_phy_params_i225 - Init PHY func ptrs. 130 * @hw: pointer to the HW structure 131 **/ 132 int 133 igc_init_phy_params_i225(struct igc_hw *hw) 134 { 135 struct igc_phy_info *phy = &hw->phy; 136 uint32_t ctrl_ext; 137 int ret_val = IGC_SUCCESS; 138 139 DEBUGFUNC("igc_init_phy_params_i225"); 140 141 if (hw->phy.media_type != igc_media_type_copper) { 142 phy->type = igc_phy_none; 143 goto out; 144 } 145 146 phy->ops.power_up = igc_power_up_phy_copper; 147 phy->ops.power_down = igc_power_down_phy_copper_base; 148 phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT_2500; 149 phy->reset_delay_us = 100; 150 phy->ops.acquire = igc_acquire_phy_base; 151 phy->ops.check_reset_block = igc_check_reset_block_generic; 152 phy->ops.commit = igc_phy_sw_reset_generic; 153 phy->ops.release = igc_release_phy_base; 154 155 ctrl_ext = IGC_READ_REG(hw, IGC_CTRL_EXT); 156 157 /* Make sure the PHY is in a good state. Several people have reported 158 * firmware leaving the PHY's page select register set to something 159 * other than the default of zero, which causes the PHY ID read to 160 * access something other than the intended register. 161 */ 162 ret_val = hw->phy.ops.reset(hw); 163 if (ret_val) 164 goto out; 165 166 IGC_WRITE_REG(hw, IGC_CTRL_EXT, ctrl_ext); 167 phy->ops.read_reg = igc_read_phy_reg_gpy; 168 phy->ops.write_reg = igc_write_phy_reg_gpy; 169 170 ret_val = igc_get_phy_id(hw); 171 /* Verify phy id and set remaining function pointers */ 172 switch (phy->id) { 173 case I225_I_PHY_ID: 174 phy->type = igc_phy_i225; 175 phy->ops.set_d0_lplu_state = igc_set_d0_lplu_state_i225; 176 phy->ops.set_d3_lplu_state = igc_set_d3_lplu_state_i225; 177 /* TODO - complete with GPY PHY information */ 178 break; 179 default: 180 ret_val = -IGC_ERR_PHY; 181 goto out; 182 } 183 184 out: 185 return ret_val; 186 } 187 188 /** 189 * igc_reset_hw_i225 - Reset hardware 190 * @hw: pointer to the HW structure 191 * 192 * This resets the hardware into a known state. 193 **/ 194 int 195 igc_reset_hw_i225(struct igc_hw *hw) 196 { 197 uint32_t ctrl; 198 int ret_val; 199 200 DEBUGFUNC("igc_reset_hw_i225"); 201 202 /* 203 * Prevent the PCI-E bus from sticking if there is no TLP connection 204 * on the last TLP read/write transaction when MAC is reset. 205 */ 206 ret_val = igc_disable_pcie_master_generic(hw); 207 if (ret_val) 208 DEBUGOUT("PCI-E Master disable polling has failed.\n"); 209 210 DEBUGOUT("Masking off all interrupts\n"); 211 IGC_WRITE_REG(hw, IGC_IMC, 0xffffffff); 212 213 IGC_WRITE_REG(hw, IGC_RCTL, 0); 214 IGC_WRITE_REG(hw, IGC_TCTL, IGC_TCTL_PSP); 215 IGC_WRITE_FLUSH(hw); 216 217 msec_delay(10); 218 219 ctrl = IGC_READ_REG(hw, IGC_CTRL); 220 221 DEBUGOUT("Issuing a global reset to MAC\n"); 222 IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_DEV_RST); 223 224 ret_val = igc_get_auto_rd_done_generic(hw); 225 if (ret_val) { 226 /* 227 * When auto config read does not complete, do not 228 * return with an error. This can happen in situations 229 * where there is no eeprom and prevents getting link. 230 */ 231 DEBUGOUT("Auto Read Done did not complete\n"); 232 } 233 234 /* Clear any pending interrupt events. */ 235 IGC_WRITE_REG(hw, IGC_IMC, 0xffffffff); 236 IGC_READ_REG(hw, IGC_ICR); 237 238 /* Install any alternate MAC address into RAR0 */ 239 ret_val = igc_check_alt_mac_addr_generic(hw); 240 241 return ret_val; 242 } 243 244 /* igc_acquire_nvm_i225 - Request for access to EEPROM 245 * @hw: pointer to the HW structure 246 * 247 * Acquire the necessary semaphores for exclusive access to the EEPROM. 248 * Set the EEPROM access request bit and wait for EEPROM access grant bit. 249 * Return successful if access grant bit set, else clear the request for 250 * EEPROM access and return -IGC_ERR_NVM (-1). 251 */ 252 int 253 igc_acquire_nvm_i225(struct igc_hw *hw) 254 { 255 int ret_val; 256 257 DEBUGFUNC("igc_acquire_nvm_i225"); 258 259 ret_val = igc_acquire_swfw_sync_i225(hw, IGC_SWFW_EEP_SM); 260 261 return ret_val; 262 } 263 264 /* igc_release_nvm_i225 - Release exclusive access to EEPROM 265 * @hw: pointer to the HW structure 266 * 267 * Stop any current commands to the EEPROM and clear the EEPROM request bit, 268 * then release the semaphores acquired. 269 */ 270 void 271 igc_release_nvm_i225(struct igc_hw *hw) 272 { 273 DEBUGFUNC("igc_release_nvm_i225"); 274 275 igc_release_swfw_sync_i225(hw, IGC_SWFW_EEP_SM); 276 } 277 278 /* igc_acquire_swfw_sync_i225 - Acquire SW/FW semaphore 279 * @hw: pointer to the HW structure 280 * @mask: specifies which semaphore to acquire 281 * 282 * Acquire the SW/FW semaphore to access the PHY or NVM. The mask 283 * will also specify which port we're acquiring the lock for. 284 */ 285 int 286 igc_acquire_swfw_sync_i225(struct igc_hw *hw, uint16_t mask) 287 { 288 uint32_t swfw_sync; 289 uint32_t swmask = mask; 290 uint32_t fwmask = mask << 16; 291 int ret_val = IGC_SUCCESS; 292 int i = 0, timeout = 200; /* FIXME: find real value to use here */ 293 294 DEBUGFUNC("igc_acquire_swfw_sync_i225"); 295 296 while (i < timeout) { 297 if (igc_get_hw_semaphore_i225(hw)) { 298 ret_val = -IGC_ERR_SWFW_SYNC; 299 goto out; 300 } 301 302 swfw_sync = IGC_READ_REG(hw, IGC_SW_FW_SYNC); 303 if (!(swfw_sync & (fwmask | swmask))) 304 break; 305 306 /* Firmware currently using resource (fwmask) 307 * or other software thread using resource (swmask) 308 */ 309 igc_put_hw_semaphore_generic(hw); 310 msec_delay(5); 311 i++; 312 } 313 314 if (i == timeout) { 315 DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); 316 ret_val = -IGC_ERR_SWFW_SYNC; 317 goto out; 318 } 319 320 swfw_sync |= swmask; 321 IGC_WRITE_REG(hw, IGC_SW_FW_SYNC, swfw_sync); 322 323 igc_put_hw_semaphore_generic(hw); 324 325 out: 326 return ret_val; 327 } 328 329 /* igc_release_swfw_sync_i225 - Release SW/FW semaphore 330 * @hw: pointer to the HW structure 331 * @mask: specifies which semaphore to acquire 332 * 333 * Release the SW/FW semaphore used to access the PHY or NVM. The mask 334 * will also specify which port we're releasing the lock for. 335 */ 336 void 337 igc_release_swfw_sync_i225(struct igc_hw *hw, uint16_t mask) 338 { 339 uint32_t swfw_sync; 340 341 DEBUGFUNC("igc_release_swfw_sync_i225"); 342 343 while (igc_get_hw_semaphore_i225(hw) != IGC_SUCCESS) 344 ; /* Empty */ 345 346 swfw_sync = IGC_READ_REG(hw, IGC_SW_FW_SYNC); 347 swfw_sync &= ~mask; 348 IGC_WRITE_REG(hw, IGC_SW_FW_SYNC, swfw_sync); 349 350 igc_put_hw_semaphore_generic(hw); 351 } 352 353 /* 354 * igc_setup_copper_link_i225 - Configure copper link settings 355 * @hw: pointer to the HW structure 356 * 357 * Configures the link for auto-neg or forced speed and duplex. Then we check 358 * for link, once link is established calls to configure collision distance 359 * and flow control are called. 360 */ 361 int 362 igc_setup_copper_link_i225(struct igc_hw *hw) 363 { 364 uint32_t ctrl, phpm_reg; 365 int ret_val; 366 367 DEBUGFUNC("igc_setup_copper_link_i225"); 368 369 ctrl = IGC_READ_REG(hw, IGC_CTRL); 370 ctrl |= IGC_CTRL_SLU; 371 ctrl &= ~(IGC_CTRL_FRCSPD | IGC_CTRL_FRCDPX); 372 IGC_WRITE_REG(hw, IGC_CTRL, ctrl); 373 374 phpm_reg = IGC_READ_REG(hw, IGC_I225_PHPM); 375 phpm_reg &= ~IGC_I225_PHPM_GO_LINKD; 376 IGC_WRITE_REG(hw, IGC_I225_PHPM, phpm_reg); 377 378 ret_val = igc_setup_copper_link_generic(hw); 379 380 return ret_val; 381 } 382 383 /* igc_get_hw_semaphore_i225 - Acquire hardware semaphore 384 * @hw: pointer to the HW structure 385 * 386 * Acquire the HW semaphore to access the PHY or NVM 387 */ 388 int 389 igc_get_hw_semaphore_i225(struct igc_hw *hw) 390 { 391 uint32_t swsm; 392 int timeout = hw->nvm.word_size + 1; 393 int i = 0; 394 395 DEBUGFUNC("igc_get_hw_semaphore_i225"); 396 397 /* Get the SW semaphore */ 398 while (i < timeout) { 399 swsm = IGC_READ_REG(hw, IGC_SWSM); 400 if (!(swsm & IGC_SWSM_SMBI)) 401 break; 402 403 DELAY(50); 404 i++; 405 } 406 407 if (i == timeout) { 408 /* In rare circumstances, the SW semaphore may already be held 409 * unintentionally. Clear the semaphore once before giving up. 410 */ 411 if (hw->dev_spec._i225.clear_semaphore_once) { 412 hw->dev_spec._i225.clear_semaphore_once = false; 413 igc_put_hw_semaphore_generic(hw); 414 for (i = 0; i < timeout; i++) { 415 swsm = IGC_READ_REG(hw, IGC_SWSM); 416 if (!(swsm & IGC_SWSM_SMBI)) 417 break; 418 419 DELAY(50); 420 } 421 } 422 423 /* If we do not have the semaphore here, we have to give up. */ 424 if (i == timeout) { 425 DEBUGOUT("Driver can't access device -\n"); 426 DEBUGOUT("SMBI bit is set.\n"); 427 return -IGC_ERR_NVM; 428 } 429 } 430 431 /* Get the FW semaphore. */ 432 for (i = 0; i < timeout; i++) { 433 swsm = IGC_READ_REG(hw, IGC_SWSM); 434 IGC_WRITE_REG(hw, IGC_SWSM, swsm | IGC_SWSM_SWESMBI); 435 436 /* Semaphore acquired if bit latched */ 437 if (IGC_READ_REG(hw, IGC_SWSM) & IGC_SWSM_SWESMBI) 438 break; 439 440 DELAY(50); 441 } 442 443 if (i == timeout) { 444 /* Release semaphores */ 445 igc_put_hw_semaphore_generic(hw); 446 DEBUGOUT("Driver can't access the NVM\n"); 447 return -IGC_ERR_NVM; 448 } 449 450 return IGC_SUCCESS; 451 } 452 453 /* igc_read_nvm_srrd_i225 - Reads Shadow Ram using EERD register 454 * @hw: pointer to the HW structure 455 * @offset: offset of word in the Shadow Ram to read 456 * @words: number of words to read 457 * @data: word read from the Shadow Ram 458 * 459 * Reads a 16 bit word from the Shadow Ram using the EERD register. 460 * Uses necessary synchronization semaphores. 461 */ 462 int 463 igc_read_nvm_srrd_i225(struct igc_hw *hw, uint16_t offset, uint16_t words, 464 uint16_t *data) 465 { 466 uint16_t i, count; 467 int status = IGC_SUCCESS; 468 469 DEBUGFUNC("igc_read_nvm_srrd_i225"); 470 471 /* We cannot hold synchronization semaphores for too long, 472 * because of forceful takeover procedure. However it is more efficient 473 * to read in bursts than synchronizing access for each word. 474 */ 475 for (i = 0; i < words; i += IGC_EERD_EEWR_MAX_COUNT) { 476 count = (words - i) / IGC_EERD_EEWR_MAX_COUNT > 0 ? 477 IGC_EERD_EEWR_MAX_COUNT : (words - i); 478 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) { 479 status = igc_read_nvm_eerd(hw, offset, count, data + i); 480 hw->nvm.ops.release(hw); 481 } else { 482 status = IGC_ERR_SWFW_SYNC; 483 } 484 485 if (status != IGC_SUCCESS) 486 break; 487 } 488 489 return status; 490 } 491 492 /* igc_write_nvm_srwr_i225 - Write to Shadow RAM using EEWR 493 * @hw: pointer to the HW structure 494 * @offset: offset within the Shadow RAM to be written to 495 * @words: number of words to write 496 * @data: 16 bit word(s) to be written to the Shadow RAM 497 * 498 * Writes data to Shadow RAM at offset using EEWR register. 499 * 500 * If igc_update_nvm_checksum is not called after this function , the 501 * data will not be committed to FLASH and also Shadow RAM will most likely 502 * contain an invalid checksum. 503 * 504 * If error code is returned, data and Shadow RAM may be inconsistent - buffer 505 * partially written. 506 */ 507 int 508 igc_write_nvm_srwr_i225(struct igc_hw *hw, uint16_t offset, uint16_t words, 509 uint16_t *data) 510 { 511 uint16_t i, count; 512 int status = IGC_SUCCESS; 513 514 DEBUGFUNC("igc_write_nvm_srwr_i225"); 515 516 /* We cannot hold synchronization semaphores for too long, 517 * because of forceful takeover procedure. However it is more efficient 518 * to write in bursts than synchronizing access for each word. 519 */ 520 for (i = 0; i < words; i += IGC_EERD_EEWR_MAX_COUNT) { 521 count = (words - i) / IGC_EERD_EEWR_MAX_COUNT > 0 ? 522 IGC_EERD_EEWR_MAX_COUNT : (words - i); 523 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) { 524 status = __igc_write_nvm_srwr(hw, offset, count, 525 data + i); 526 hw->nvm.ops.release(hw); 527 } else 528 status = IGC_ERR_SWFW_SYNC; 529 530 if (status != IGC_SUCCESS) 531 break; 532 } 533 534 return status; 535 } 536 537 /* __igc_write_nvm_srwr - Write to Shadow Ram using EEWR 538 * @hw: pointer to the HW structure 539 * @offset: offset within the Shadow Ram to be written to 540 * @words: number of words to write 541 * @data: 16 bit word(s) to be written to the Shadow Ram 542 * 543 * Writes data to Shadow Ram at offset using EEWR register. 544 * 545 * If igc_update_nvm_checksum is not called after this function , the 546 * Shadow Ram will most likely contain an invalid checksum. 547 */ 548 int 549 __igc_write_nvm_srwr(struct igc_hw *hw, uint16_t offset, uint16_t words, 550 uint16_t *data) 551 { 552 struct igc_nvm_info *nvm = &hw->nvm; 553 uint32_t i, k, eewr = 0; 554 uint32_t attempts = 100000; 555 int ret_val = IGC_SUCCESS; 556 557 DEBUGFUNC("__igc_write_nvm_srwr"); 558 559 /* A check for invalid values: offset too large, too many words, 560 * too many words for the offset, and not enough words. 561 */ 562 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || 563 (words == 0)) { 564 DEBUGOUT("nvm parameter(s) out of bounds\n"); 565 ret_val = -IGC_ERR_NVM; 566 goto out; 567 } 568 569 for (i = 0; i < words; i++) { 570 eewr = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) | 571 (data[i] << IGC_NVM_RW_REG_DATA) | IGC_NVM_RW_REG_START; 572 573 IGC_WRITE_REG(hw, IGC_SRWR, eewr); 574 575 for (k = 0; k < attempts; k++) { 576 if (IGC_NVM_RW_REG_DONE & IGC_READ_REG(hw, IGC_SRWR)) { 577 ret_val = IGC_SUCCESS; 578 break; 579 } 580 DELAY(5); 581 } 582 583 if (ret_val != IGC_SUCCESS) { 584 DEBUGOUT("Shadow RAM write EEWR timed out\n"); 585 break; 586 } 587 } 588 589 out: 590 return ret_val; 591 } 592 593 /* igc_validate_nvm_checksum_i225 - Validate EEPROM checksum 594 * @hw: pointer to the HW structure 595 * 596 * Calculates the EEPROM checksum by reading/adding each word of the EEPROM 597 * and then verifies that the sum of the EEPROM is equal to 0xBABA. 598 */ 599 int 600 igc_validate_nvm_checksum_i225(struct igc_hw *hw) 601 { 602 int status = IGC_SUCCESS; 603 int (*read_op_ptr)(struct igc_hw *, uint16_t, uint16_t, uint16_t *); 604 605 DEBUGFUNC("igc_validate_nvm_checksum_i225"); 606 607 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) { 608 /* Replace the read function with semaphore grabbing with 609 * the one that skips this for a while. 610 * We have semaphore taken already here. 611 */ 612 read_op_ptr = hw->nvm.ops.read; 613 hw->nvm.ops.read = igc_read_nvm_eerd; 614 615 status = igc_validate_nvm_checksum_generic(hw); 616 617 /* Revert original read operation. */ 618 hw->nvm.ops.read = read_op_ptr; 619 620 hw->nvm.ops.release(hw); 621 } else { 622 status = IGC_ERR_SWFW_SYNC; 623 } 624 625 return status; 626 } 627 628 /* igc_update_nvm_checksum_i225 - Update EEPROM checksum 629 * @hw: pointer to the HW structure 630 * 631 * Updates the EEPROM checksum by reading/adding each word of the EEPROM 632 * up to the checksum. Then calculates the EEPROM checksum and writes the 633 * value to the EEPROM. Next commit EEPROM data onto the Flash. 634 */ 635 int 636 igc_update_nvm_checksum_i225(struct igc_hw *hw) 637 { 638 uint16_t checksum = 0; 639 uint16_t i, nvm_data; 640 int ret_val; 641 642 DEBUGFUNC("igc_update_nvm_checksum_i225"); 643 644 /* Read the first word from the EEPROM. If this times out or fails, do 645 * not continue or we could be in for a very long wait while every 646 * EEPROM read fails 647 */ 648 ret_val = igc_read_nvm_eerd(hw, 0, 1, &nvm_data); 649 if (ret_val != IGC_SUCCESS) { 650 DEBUGOUT("EEPROM read failed\n"); 651 goto out; 652 } 653 654 if (hw->nvm.ops.acquire(hw) == IGC_SUCCESS) { 655 /* Do not use hw->nvm.ops.write, hw->nvm.ops.read 656 * because we do not want to take the synchronization 657 * semaphores twice here. 658 */ 659 660 for (i = 0; i < NVM_CHECKSUM_REG; i++) { 661 ret_val = igc_read_nvm_eerd(hw, i, 1, &nvm_data); 662 if (ret_val) { 663 hw->nvm.ops.release(hw); 664 DEBUGOUT("NVM Read Error while updating\n"); 665 DEBUGOUT("checksum.\n"); 666 goto out; 667 } 668 checksum += nvm_data; 669 } 670 checksum = (uint16_t)NVM_SUM - checksum; 671 ret_val = __igc_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1, 672 &checksum); 673 if (ret_val != IGC_SUCCESS) { 674 hw->nvm.ops.release(hw); 675 DEBUGOUT("NVM Write Error while updating checksum.\n"); 676 goto out; 677 } 678 679 hw->nvm.ops.release(hw); 680 681 ret_val = igc_update_flash_i225(hw); 682 } else { 683 ret_val = IGC_ERR_SWFW_SYNC; 684 } 685 out: 686 return ret_val; 687 } 688 689 /* igc_get_flash_presence_i225 - Check if flash device is detected. 690 * @hw: pointer to the HW structure 691 */ 692 bool 693 igc_get_flash_presence_i225(struct igc_hw *hw) 694 { 695 uint32_t eec = 0; 696 bool ret_val = false; 697 698 DEBUGFUNC("igc_get_flash_presence_i225"); 699 700 eec = IGC_READ_REG(hw, IGC_EECD); 701 702 if (eec & IGC_EECD_FLASH_DETECTED_I225) 703 ret_val = true; 704 705 return ret_val; 706 } 707 708 /* igc_set_flsw_flash_burst_counter_i225 - sets FLSW NVM Burst 709 * Counter in FLSWCNT register. 710 * 711 * @hw: pointer to the HW structure 712 * @burst_counter: size in bytes of the Flash burst to read or write 713 */ 714 int 715 igc_set_flsw_flash_burst_counter_i225(struct igc_hw *hw, uint32_t burst_counter) 716 { 717 int ret_val = IGC_SUCCESS; 718 719 DEBUGFUNC("igc_set_flsw_flash_burst_counter_i225"); 720 721 /* Validate input data */ 722 if (burst_counter < IGC_I225_SHADOW_RAM_SIZE) { 723 /* Write FLSWCNT - burst counter */ 724 IGC_WRITE_REG(hw, IGC_I225_FLSWCNT, burst_counter); 725 } else { 726 ret_val = IGC_ERR_INVALID_ARGUMENT; 727 } 728 729 return ret_val; 730 } 731 732 733 /* igc_write_erase_flash_command_i225 - write/erase to a sector 734 * region on a given address. 735 * 736 * @hw: pointer to the HW structure 737 * @opcode: opcode to be used for the write command 738 * @address: the offset to write into the FLASH image 739 */ 740 int 741 igc_write_erase_flash_command_i225(struct igc_hw *hw, uint32_t opcode, 742 uint32_t address) 743 { 744 uint32_t flswctl = 0; 745 int timeout = IGC_NVM_GRANT_ATTEMPTS; 746 int ret_val = IGC_SUCCESS; 747 748 DEBUGFUNC("igc_write_erase_flash_command_i225"); 749 750 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL); 751 /* Polling done bit on FLSWCTL register */ 752 while (timeout) { 753 if (flswctl & IGC_FLSWCTL_DONE) 754 break; 755 DELAY(5); 756 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL); 757 timeout--; 758 } 759 760 if (!timeout) { 761 DEBUGOUT("Flash transaction was not done\n"); 762 return -IGC_ERR_NVM; 763 } 764 765 /* Build and issue command on FLSWCTL register */ 766 flswctl = address | opcode; 767 IGC_WRITE_REG(hw, IGC_I225_FLSWCTL, flswctl); 768 769 /* Check if issued command is valid on FLSWCTL register */ 770 flswctl = IGC_READ_REG(hw, IGC_I225_FLSWCTL); 771 if (!(flswctl & IGC_FLSWCTL_CMDV)) { 772 DEBUGOUT("Write flash command failed\n"); 773 ret_val = IGC_ERR_INVALID_ARGUMENT; 774 } 775 776 return ret_val; 777 } 778 779 /* igc_update_flash_i225 - Commit EEPROM to the flash 780 * if fw_valid_bit is set, FW is active. setting FLUPD bit in EEC 781 * register makes the FW load the internal shadow RAM into the flash. 782 * Otherwise, fw_valid_bit is 0. if FL_SECU.block_prtotected_sw = 0 783 * then FW is not active so the SW is responsible shadow RAM dump. 784 * 785 * @hw: pointer to the HW structure 786 */ 787 int 788 igc_update_flash_i225(struct igc_hw *hw) 789 { 790 uint32_t block_sw_protect = 1; 791 uint32_t i, flup, fw_valid_bit; 792 uint16_t current_offset; 793 uint16_t base_address = 0x0; 794 uint16_t current_offset_data = 0; 795 int ret_val = 0; 796 797 DEBUGFUNC("igc_update_flash_i225"); 798 799 block_sw_protect = IGC_READ_REG(hw, IGC_I225_FLSECU) & 800 IGC_FLSECU_BLK_SW_ACCESS_I225; 801 802 fw_valid_bit = IGC_READ_REG(hw, IGC_FWSM) & IGC_FWSM_FW_VALID_I225; 803 if (fw_valid_bit) { 804 ret_val = igc_pool_flash_update_done_i225(hw); 805 if (ret_val == -IGC_ERR_NVM) { 806 DEBUGOUT("Flash update time out\n"); 807 goto out; 808 } 809 810 flup = IGC_READ_REG(hw, IGC_EECD) | IGC_EECD_FLUPD_I225; 811 IGC_WRITE_REG(hw, IGC_EECD, flup); 812 813 ret_val = igc_pool_flash_update_done_i225(hw); 814 if (ret_val == IGC_SUCCESS) 815 DEBUGOUT("Flash update complete\n"); 816 else 817 DEBUGOUT("Flash update time out\n"); 818 } else if (!block_sw_protect) { 819 /* FW is not active and security protection is disabled. 820 * therefore, SW is in charge of shadow RAM dump. 821 * Check which sector is valid. if sector 0 is valid, 822 * base address remains 0x0. otherwise, sector 1 is 823 * valid and it's base address is 0x1000 824 */ 825 if (IGC_READ_REG(hw, IGC_EECD) & IGC_EECD_SEC1VAL_I225) 826 base_address = 0x1000; 827 828 /* Valid sector erase */ 829 ret_val = igc_write_erase_flash_command_i225(hw, 830 IGC_I225_ERASE_CMD_OPCODE, base_address); 831 if (!ret_val) { 832 DEBUGOUT("Sector erase failed\n"); 833 goto out; 834 } 835 836 current_offset = base_address; 837 838 /* Write */ 839 for (i = 0; i < IGC_I225_SHADOW_RAM_SIZE / 2; i++) { 840 /* Set burst write length */ 841 ret_val = igc_set_flsw_flash_burst_counter_i225(hw, 842 0x2); 843 if (ret_val != IGC_SUCCESS) 844 break; 845 846 /* Set address and opcode */ 847 ret_val = igc_write_erase_flash_command_i225(hw, 848 IGC_I225_WRITE_CMD_OPCODE, 2 * current_offset); 849 if (ret_val != IGC_SUCCESS) 850 break; 851 852 ret_val = igc_read_nvm_eerd(hw, current_offset, 1, 853 ¤t_offset_data); 854 if (ret_val) { 855 DEBUGOUT("Failed to read from EEPROM\n"); 856 goto out; 857 } 858 859 /* Write CurrentOffseData to FLSWDATA register */ 860 IGC_WRITE_REG(hw, IGC_I225_FLSWDATA, 861 current_offset_data); 862 current_offset++; 863 864 /* Wait till operation has finished */ 865 ret_val = igc_poll_eerd_eewr_done(hw, 866 IGC_NVM_POLL_READ); 867 if (ret_val) 868 break; 869 870 DELAY(1000); 871 } 872 } 873 out: 874 return ret_val; 875 } 876 877 /* igc_pool_flash_update_done_i225 - Pool FLUDONE status. 878 * @hw: pointer to the HW structure 879 */ 880 int 881 igc_pool_flash_update_done_i225(struct igc_hw *hw) 882 { 883 uint32_t i, reg; 884 int ret_val = -IGC_ERR_NVM; 885 886 DEBUGFUNC("igc_pool_flash_update_done_i225"); 887 888 for (i = 0; i < IGC_FLUDONE_ATTEMPTS; i++) { 889 reg = IGC_READ_REG(hw, IGC_EECD); 890 if (reg & IGC_EECD_FLUDONE_I225) { 891 ret_val = IGC_SUCCESS; 892 break; 893 } 894 DELAY(5); 895 } 896 897 return ret_val; 898 } 899 900 /* igc_set_ltr_i225 - Set Latency Tolerance Reporting thresholds. 901 * @hw: pointer to the HW structure 902 * @link: bool indicating link status 903 * 904 * Set the LTR thresholds based on the link speed (Mbps), EEE, and DMAC 905 * settings, otherwise specify that there is no LTR requirement. 906 */ 907 int 908 igc_set_ltr_i225(struct igc_hw *hw, bool link) 909 { 910 uint16_t speed, duplex; 911 uint32_t tw_system, ltrc, ltrv, ltr_min, ltr_max, scale_min, scale_max; 912 int size; 913 914 DEBUGFUNC("igc_set_ltr_i225"); 915 916 /* If we do not have link, LTR thresholds are zero. */ 917 if (link) { 918 hw->mac.ops.get_link_up_info(hw, &speed, &duplex); 919 920 /* Check if using copper interface with EEE enabled or if the 921 * link speed is 10 Mbps. 922 */ 923 if ((hw->phy.media_type == igc_media_type_copper) && 924 !(hw->dev_spec._i225.eee_disable) && 925 (speed != SPEED_10)) { 926 /* EEE enabled, so send LTRMAX threshold. */ 927 ltrc = IGC_READ_REG(hw, IGC_LTRC) | IGC_LTRC_EEEMS_EN; 928 IGC_WRITE_REG(hw, IGC_LTRC, ltrc); 929 930 /* Calculate tw_system (nsec). */ 931 if (speed == SPEED_100) { 932 tw_system = ((IGC_READ_REG(hw, IGC_EEE_SU) & 933 IGC_TW_SYSTEM_100_MASK) >> 934 IGC_TW_SYSTEM_100_SHIFT) * 500; 935 } else { 936 tw_system = (IGC_READ_REG(hw, IGC_EEE_SU) & 937 IGC_TW_SYSTEM_1000_MASK) * 500; 938 } 939 } else { 940 tw_system = 0; 941 } 942 943 /* Get the Rx packet buffer size. */ 944 size = IGC_READ_REG(hw, IGC_RXPBS) & IGC_RXPBS_SIZE_I225_MASK; 945 946 /* Calculations vary based on DMAC settings. */ 947 if (IGC_READ_REG(hw, IGC_DMACR) & IGC_DMACR_DMAC_EN) { 948 size -= (IGC_READ_REG(hw, IGC_DMACR) & 949 IGC_DMACR_DMACTHR_MASK) >> IGC_DMACR_DMACTHR_SHIFT; 950 /* Convert size to bits. */ 951 size *= 1024 * 8; 952 } else { 953 /* Convert size to bytes, subtract the MTU, and then 954 * convert the size to bits. 955 */ 956 size *= 1024; 957 size -= hw->dev_spec._i225.mtu; 958 size *= 8; 959 } 960 961 if (size < 0) { 962 DEBUGOUT1("Invalid effective Rx buffer size %d\n", 963 size); 964 return -IGC_ERR_CONFIG; 965 } 966 967 /* Calculate the thresholds. Since speed is in Mbps, simplify 968 * the calculation by multiplying size/speed by 1000 for result 969 * to be in nsec before dividing by the scale in nsec. Set the 970 * scale such that the LTR threshold fits in the register. 971 */ 972 ltr_min = (1000 * size) / speed; 973 ltr_max = ltr_min + tw_system; 974 scale_min = (ltr_min / 1024) < 1024 ? IGC_LTRMINV_SCALE_1024 : 975 IGC_LTRMINV_SCALE_32768; 976 scale_max = (ltr_max / 1024) < 1024 ? IGC_LTRMAXV_SCALE_1024 : 977 IGC_LTRMAXV_SCALE_32768; 978 ltr_min /= scale_min == IGC_LTRMINV_SCALE_1024 ? 1024 : 32768; 979 ltr_max /= scale_max == IGC_LTRMAXV_SCALE_1024 ? 1024 : 32768; 980 981 /* Only write the LTR thresholds if they differ from before. */ 982 ltrv = IGC_READ_REG(hw, IGC_LTRMINV); 983 if (ltr_min != (ltrv & IGC_LTRMINV_LTRV_MASK)) { 984 ltrv = IGC_LTRMINV_LSNP_REQ | ltr_min | 985 (scale_min << IGC_LTRMINV_SCALE_SHIFT); 986 IGC_WRITE_REG(hw, IGC_LTRMINV, ltrv); 987 } 988 989 ltrv = IGC_READ_REG(hw, IGC_LTRMAXV); 990 if (ltr_max != (ltrv & IGC_LTRMAXV_LTRV_MASK)) { 991 ltrv = IGC_LTRMAXV_LSNP_REQ | ltr_max | 992 (scale_min << IGC_LTRMAXV_SCALE_SHIFT); 993 IGC_WRITE_REG(hw, IGC_LTRMAXV, ltrv); 994 } 995 } 996 997 return IGC_SUCCESS; 998 } 999 1000 /* igc_check_for_link_i225 - Check for link 1001 * @hw: pointer to the HW structure 1002 * 1003 * Checks to see of the link status of the hardware has changed. If a 1004 * change in link status has been detected, then we read the PHY registers 1005 * to get the current speed/duplex if link exists. 1006 */ 1007 int 1008 igc_check_for_link_i225(struct igc_hw *hw) 1009 { 1010 struct igc_mac_info *mac = &hw->mac; 1011 int ret_val; 1012 bool link = false; 1013 1014 DEBUGFUNC("igc_check_for_link_i225"); 1015 1016 /* We only want to go out to the PHY registers to see if 1017 * Auto-Neg has completed and/or if our link status has 1018 * changed. The get_link_status flag is set upon receiving 1019 * a Link Status Change or Rx Sequence Error interrupt. 1020 */ 1021 if (!mac->get_link_status) { 1022 ret_val = IGC_SUCCESS; 1023 goto out; 1024 } 1025 1026 /* First we want to see if the MII Status Register reports 1027 * link. If so, then we want to get the current speed/duplex 1028 * of the PHY. 1029 */ 1030 ret_val = igc_phy_has_link_generic(hw, 1, 0, &link); 1031 if (ret_val) 1032 goto out; 1033 1034 if (!link) 1035 goto out; /* No link detected */ 1036 1037 /* First we want to see if the MII Status Register reports 1038 * link. If so, then we want to get the current speed/duplex 1039 * of the PHY. 1040 */ 1041 ret_val = igc_phy_has_link_generic(hw, 1, 0, &link); 1042 if (ret_val) 1043 goto out; 1044 1045 if (!link) 1046 goto out; /* No link detected */ 1047 1048 mac->get_link_status = false; 1049 1050 /* Check if there was DownShift, must be checked 1051 * immediately after link-up 1052 */ 1053 igc_check_downshift_generic(hw); 1054 1055 /* If we are forcing speed/duplex, then we simply return since 1056 * we have already determined whether we have link or not. 1057 */ 1058 if (!mac->autoneg) 1059 goto out; 1060 1061 /* Auto-Neg is enabled. Auto Speed Detection takes care 1062 * of MAC speed/duplex configuration. So we only need to 1063 * configure Collision Distance in the MAC. 1064 */ 1065 mac->ops.config_collision_dist(hw); 1066 1067 /* Configure Flow Control now that Auto-Neg has completed. 1068 * First, we need to restore the desired flow control 1069 * settings because we may have had to re-autoneg with a 1070 * different link partner. 1071 */ 1072 ret_val = igc_config_fc_after_link_up_generic(hw); 1073 if (ret_val) 1074 DEBUGOUT("Error configuring flow control\n"); 1075 out: 1076 /* Now that we are aware of our link settings, we can set the LTR 1077 * thresholds. 1078 */ 1079 ret_val = igc_set_ltr_i225(hw, link); 1080 1081 return ret_val; 1082 } 1083 1084 /* igc_init_function_pointers_i225 - Init func ptrs. 1085 * @hw: pointer to the HW structure 1086 * 1087 * Called to initialize all function pointers and parameters. 1088 */ 1089 void 1090 igc_init_function_pointers_i225(struct igc_hw *hw) 1091 { 1092 igc_init_mac_ops_generic(hw); 1093 igc_init_phy_ops_generic(hw); 1094 igc_init_nvm_ops_generic(hw); 1095 hw->mac.ops.init_params = igc_init_mac_params_i225; 1096 hw->nvm.ops.init_params = igc_init_nvm_params_i225; 1097 hw->phy.ops.init_params = igc_init_phy_params_i225; 1098 } 1099 1100 /* igc_init_hw_i225 - Init hw for I225 1101 * @hw: pointer to the HW structure 1102 * 1103 * Called to initialize hw for i225 hw family. 1104 */ 1105 int 1106 igc_init_hw_i225(struct igc_hw *hw) 1107 { 1108 int ret_val; 1109 1110 DEBUGFUNC("igc_init_hw_i225"); 1111 1112 ret_val = igc_init_hw_base(hw); 1113 return ret_val; 1114 } 1115 1116 /* 1117 * igc_set_d0_lplu_state_i225 - Set Low-Power-Link-Up (LPLU) D0 state 1118 * @hw: pointer to the HW structure 1119 * @active: true to enable LPLU, false to disable 1120 * 1121 * Note: since I225 does not actually support LPLU, this function 1122 * simply enables/disables 1G and 2.5G speeds in D0. 1123 */ 1124 int 1125 igc_set_d0_lplu_state_i225(struct igc_hw *hw, bool active) 1126 { 1127 uint32_t data; 1128 1129 DEBUGFUNC("igc_set_d0_lplu_state_i225"); 1130 1131 data = IGC_READ_REG(hw, IGC_I225_PHPM); 1132 1133 if (active) { 1134 data |= IGC_I225_PHPM_DIS_1000; 1135 data |= IGC_I225_PHPM_DIS_2500; 1136 } else { 1137 data &= ~IGC_I225_PHPM_DIS_1000; 1138 data &= ~IGC_I225_PHPM_DIS_2500; 1139 } 1140 1141 IGC_WRITE_REG(hw, IGC_I225_PHPM, data); 1142 return IGC_SUCCESS; 1143 } 1144 1145 /* 1146 * igc_set_d3_lplu_state_i225 - Set Low-Power-Link-Up (LPLU) D3 state 1147 * @hw: pointer to the HW structure 1148 * @active: true to enable LPLU, false to disable 1149 * 1150 * Note: since I225 does not actually support LPLU, this function 1151 * simply enables/disables 100M, 1G and 2.5G speeds in D3. 1152 */ 1153 int 1154 igc_set_d3_lplu_state_i225(struct igc_hw *hw, bool active) 1155 { 1156 uint32_t data; 1157 1158 DEBUGFUNC("igc_set_d3_lplu_state_i225"); 1159 1160 data = IGC_READ_REG(hw, IGC_I225_PHPM); 1161 1162 if (active) { 1163 data |= IGC_I225_PHPM_DIS_100_D3; 1164 data |= IGC_I225_PHPM_DIS_1000_D3; 1165 data |= IGC_I225_PHPM_DIS_2500_D3; 1166 } else { 1167 data &= ~IGC_I225_PHPM_DIS_100_D3; 1168 data &= ~IGC_I225_PHPM_DIS_1000_D3; 1169 data &= ~IGC_I225_PHPM_DIS_2500_D3; 1170 } 1171 1172 IGC_WRITE_REG(hw, IGC_I225_PHPM, data); 1173 return IGC_SUCCESS; 1174 } 1175 1176 /** 1177 * igc_set_eee_i225 - Enable/disable EEE support 1178 * @hw: pointer to the HW structure 1179 * @adv2p5G: boolean flag enabling 2.5G EEE advertisement 1180 * @adv1G: boolean flag enabling 1G EEE advertisement 1181 * @adv100M: boolean flag enabling 100M EEE advertisement 1182 * 1183 * Enable/disable EEE based on setting in dev_spec structure. 1184 * 1185 **/ 1186 int 1187 igc_set_eee_i225(struct igc_hw *hw, bool adv2p5G, bool adv1G, 1188 bool adv100M) 1189 { 1190 uint32_t ipcnfg, eeer; 1191 1192 DEBUGFUNC("igc_set_eee_i225"); 1193 1194 if (hw->mac.type != igc_i225 || 1195 hw->phy.media_type != igc_media_type_copper) 1196 goto out; 1197 ipcnfg = IGC_READ_REG(hw, IGC_IPCNFG); 1198 eeer = IGC_READ_REG(hw, IGC_EEER); 1199 1200 /* enable or disable per user setting */ 1201 if (!(hw->dev_spec._i225.eee_disable)) { 1202 uint32_t eee_su = IGC_READ_REG(hw, IGC_EEE_SU); 1203 1204 if (adv100M) 1205 ipcnfg |= IGC_IPCNFG_EEE_100M_AN; 1206 else 1207 ipcnfg &= ~IGC_IPCNFG_EEE_100M_AN; 1208 1209 if (adv1G) 1210 ipcnfg |= IGC_IPCNFG_EEE_1G_AN; 1211 else 1212 ipcnfg &= ~IGC_IPCNFG_EEE_1G_AN; 1213 1214 if (adv2p5G) 1215 ipcnfg |= IGC_IPCNFG_EEE_2_5G_AN; 1216 else 1217 ipcnfg &= ~IGC_IPCNFG_EEE_2_5G_AN; 1218 1219 eeer |= (IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN | 1220 IGC_EEER_LPI_FC); 1221 1222 /* This bit should not be set in normal operation. */ 1223 if (eee_su & IGC_EEE_SU_LPI_CLK_STP) 1224 DEBUGOUT("LPI Clock Stop Bit should not be set!\n"); 1225 } else { 1226 ipcnfg &= ~(IGC_IPCNFG_EEE_2_5G_AN | IGC_IPCNFG_EEE_1G_AN | 1227 IGC_IPCNFG_EEE_100M_AN); 1228 eeer &= ~(IGC_EEER_TX_LPI_EN | IGC_EEER_RX_LPI_EN | 1229 IGC_EEER_LPI_FC); 1230 } 1231 IGC_WRITE_REG(hw, IGC_IPCNFG, ipcnfg); 1232 IGC_WRITE_REG(hw, IGC_EEER, eeer); 1233 IGC_READ_REG(hw, IGC_IPCNFG); 1234 IGC_READ_REG(hw, IGC_EEER); 1235 out: 1236 1237 return IGC_SUCCESS; 1238 } 1239