📄 e1000_82571.c
字号:
static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw){ s32 ret_val; DEBUGFUNC("e1000_acquire_nvm_82571"); ret_val = e1000_get_hw_semaphore_82571(hw); if (ret_val) goto out; if (hw->mac.type != e1000_82573) ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) e1000_put_hw_semaphore_82571(hw);out: return ret_val;}/** * e1000_release_nvm_82571 - Release exclusive access to EEPROM * @hw: pointer to the HW structure * * Stop any current commands to the EEPROM and clear the EEPROM request bit. **/static void e1000_release_nvm_82571(struct e1000_hw *hw){ DEBUGFUNC("e1000_release_nvm_82571"); e1000_release_nvm_generic(hw); e1000_put_hw_semaphore_82571(hw);}/** * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface * @hw: pointer to the HW structure * @offset: offset within the EEPROM to be written to * @words: number of words to write * @data: 16 bit word(s) to be written to the EEPROM * * For non-82573 silicon, write data to EEPROM at offset using SPI interface. * * If e1000_update_nvm_checksum is not called after this function, the * EEPROM will most likley contain an invalid checksum. **/static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){ s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_nvm_82571"); switch (hw->mac.type) { case e1000_82573: ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); break; case e1000_82571: case e1000_82572: ret_val = e1000_write_nvm_spi(hw, offset, words, data); break; default: ret_val = -E1000_ERR_NVM; break; } return ret_val;}/** * e1000_update_nvm_checksum_82571 - Update EEPROM checksum * @hw: pointer to the HW structure * * Updates the EEPROM checksum by reading/adding each word of the EEPROM * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw){ u32 eecd; s32 ret_val; u16 i; DEBUGFUNC("e1000_update_nvm_checksum_82571"); ret_val = e1000_update_nvm_checksum_generic(hw); if (ret_val) goto out; /* If our nvm is an EEPROM, then we're done * otherwise, commit the checksum to the flash NVM. */ if (hw->nvm.type != e1000_nvm_flash_hw) goto out; /* Check for pending operations. */ for (i = 0; i < E1000_FLASH_UPDATES; i++) { msec_delay(1); if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) break; } if (i == E1000_FLASH_UPDATES) { ret_val = -E1000_ERR_NVM; goto out; } /* Reset the firmware if using STM opcode. */ if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) { /* The enabling of and the actual reset must be done * in two write cycles. */ E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE); E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET); } /* Commit the write to flash */ eecd = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD; E1000_WRITE_REG(hw, E1000_EECD, eecd); for (i = 0; i < E1000_FLASH_UPDATES; i++) { msec_delay(1); if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) break; } if (i == E1000_FLASH_UPDATES) { ret_val = -E1000_ERR_NVM; goto out; }out: return ret_val;}/** * e1000_validate_nvm_checksum_82571 - Validate EEPROM checksum * @hw: pointer to the HW structure * * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw){ DEBUGFUNC("e1000_validate_nvm_checksum_82571"); if (hw->nvm.type == e1000_nvm_flash_hw) e1000_fix_nvm_checksum_82571(hw); return e1000_validate_nvm_checksum_generic(hw);}/** * e1000_write_nvm_eewr_82571 - Write to EEPROM for 82573 silicon * @hw: pointer to the HW structure * @offset: offset within the EEPROM to be written to * @words: number of words to write * @data: 16 bit word(s) to be written to the EEPROM * * After checking for invalid values, poll the EEPROM to ensure the previous * command has completed before trying to write the next word. After write * poll for completion. * * If e1000_update_nvm_checksum is not called after this function, the * EEPROM will most likley contain an invalid checksum. **/static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){ struct e1000_nvm_info *nvm = &hw->nvm; u32 i, eewr = 0; s32 ret_val = 0; DEBUGFUNC("e1000_write_nvm_eewr_82571"); /* A check for invalid values: offset too large, too many words, * and not enough words. */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); ret_val = -E1000_ERR_NVM; goto out; } for (i = 0; i < words; i++) { eewr = (data[i] << E1000_NVM_RW_REG_DATA) | ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | E1000_NVM_RW_REG_START; ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); if (ret_val) break; E1000_WRITE_REG(hw, E1000_EEWR, eewr); ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); if (ret_val) break; }out: return ret_val;}/** * e1000_get_cfg_done_82571 - Poll for configuration done * @hw: pointer to the HW structure * * Reads the management control register for the config done bit to be set. **/static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw){ s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_get_cfg_done_82571"); while (timeout) { if (E1000_READ_REG(hw, E1000_EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) break; msec_delay(1); timeout--; } if (!timeout) { DEBUGOUT("MNG configuration cycle has not completed.\n"); ret_val = -E1000_ERR_RESET; goto out; }out: return ret_val;}/** * e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state * @hw: pointer to the HW structure * @active: TRUE to enable LPLU, FALSE to disable * * Sets the LPLU D0 state according to the active flag. When activating LPLU * this function also disables smart speed and vice versa. LPLU will not be * activated unless the device autonegotiation advertisement meets standards * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function * pointer entry point only called by PHY setup routines. **/static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, boolean_t active){ struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 data; DEBUGFUNC("e1000_set_d0_lplu_state_82571"); ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); if (ret_val) goto out; if (active) { data |= IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else { data &= ~IGP02E1000_PM_D0_LPLU; ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); /* LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } }out: return ret_val;}/** * e1000_reset_hw_82571 - Reset hardware * @hw: pointer to the HW structure * * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/static s32 e1000_reset_hw_82571(struct e1000_hw *hw){ u32 ctrl, extcnf_ctrl, ctrl_ext, icr; s32 ret_val; u16 i = 0; DEBUGFUNC("e1000_reset_hw_82571"); /* Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); if (ret_val) { DEBUGOUT("PCI-E Master disable polling has failed.\n"); } DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); E1000_WRITE_REG(hw, E1000_RCTL, 0); E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); E1000_WRITE_FLUSH(hw); msec_delay(10); /* Must acquire the MDIO ownership before MAC reset. * Ownership defaults to firmware after a reset. */ if (hw->mac.type == e1000_82573) { extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; do { E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) break; extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; msec_delay(2); i++; } while (i < MDIO_OWNERSHIP_TIMEOUT); } ctrl = E1000_READ_REG(hw, E1000_CTRL); DEBUGOUT("Issuing a global reset to MAC\n"); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); if (hw->nvm.type == e1000_nvm_flash_hw) { usec_delay(10); ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_EE_RST; E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); E1000_WRITE_FLUSH(hw); } ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) /* We don't want to continue accessing MAC registers. */ goto out; /* Phy configuration from NVM just starts after EECD_AUTO_RD is set. * Need to wait for Phy configuration completion before accessing * NVM and Phy. */ if (hw->mac.type == e1000_82573) msec_delay(25); /* Clear any pending interrupt events. */ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); icr = E1000_READ_REG(hw, E1000_ICR);out: return ret_val;}/** * e1000_init_hw_82571 - Initialize hardware * @hw: pointer to the HW structure * * This inits the hardware readying it for operation. **/static s32 e1000_init_hw_82571(struct e1000_hw *hw){ struct e1000_mac_info *mac = &hw->mac; u32 reg_data; s32 ret_val; u16 i, rar_count = mac->rar_entry_count; DEBUGFUNC("e1000_init_hw_82571"); e1000_initialize_hw_bits_82571(hw); /* Initialize identification LED */ ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); goto out; } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); e1000_clear_vfta(hw); /* Setup the receive address. */ /* If, however, a locally administered address was assigned to the * 82571, we must reserve a RAR for it to work around an issue where * resetting one port will reload the MAC on the other port. */ if (e1000_get_laa_state_82571(hw) == TRUE) rar_count--; e1000_init_rx_addrs_generic(hw, rar_count); /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); /* Setup link and flow control */ ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; E1000_WRITE_REG(hw, E1000_TXDCTL, reg_data); /* ...for both queues. */ if (mac->type != e1000_82573) { reg_data = E1000_READ_REG(hw, E1000_TXDCTL1); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -