⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e1000_82571.c

📁 Intel 82546系列lan driver源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/** *  e1000_acquire_nvm_82571 - Request for access to the EEPROM *  @hw: pointer to the HW structure * *  To gain access to the EEPROM, first we must obtain a hardware semaphore. *  Then for non-82573 hardware, set the EEPROM access request bit and wait *  for EEPROM access grant bit.  If the access grant bit is not set, release *  hardware semaphore. **/static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw){	s32 ret_val;	ret_val = e1000_get_hw_semaphore_82571(hw);	if (ret_val)		goto out;	if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)		ret_val = e1000e_acquire_nvm(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){	e1000e_release_nvm(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 likely 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;	switch (hw->mac.type) {	case e1000_82573:	case e1000_82574:		ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);		break;	case e1000_82571:	case e1000_82572:		ret_val = e1000e_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;	ret_val = e1000e_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++) {		msleep(1);		if ((er32(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 ((er32(FLOP) & 0xFF00) == E1000_STM_OPCODE) {		/*		 * The enabling of and the actual reset must be done		 * in two write cycles.		 */		ew32(HICR, E1000_HICR_FW_RESET_ENABLE);		e1e_flush();		ew32(HICR, E1000_HICR_FW_RESET);	}	/* Commit the write to flash */	eecd = er32(EECD) | E1000_EECD_FLUPD;	ew32(EECD, eecd);	for (i = 0; i < E1000_FLASH_UPDATES; i++) {		msleep(1);		if ((er32(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){	if (hw->nvm.type == e1000_nvm_flash_hw)		e1000_fix_nvm_checksum_82571(hw);	return e1000e_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 likely 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;	/*	 * 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)) {		e_dbg("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 = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);		if (ret_val)			break;		ew32(EEWR, eewr);		ret_val = e1000e_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;	while (timeout) {		if (er32(EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0)			break;		msleep(1);		timeout--;	}	if (!timeout) {		e_dbg("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, bool active){	struct e1000_phy_info *phy = &hw->phy;	s32 ret_val = E1000_SUCCESS;	u16 data;	if (!(phy->ops.read_reg))		goto out;	ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);	if (ret_val)		goto out;	if (active) {		data |= IGP02E1000_PM_D0_LPLU;		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT,		                             data);		if (ret_val)			goto out;		/* When LPLU is enabled, we should disable SmartSpeed */		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,		                            &data);		data &= ~IGP01E1000_PSCFR_SMART_SPEED;		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,		                             data);		if (ret_val)			goto out;	} else {		data &= ~IGP02E1000_PM_D0_LPLU;		ret_val = e1e_wphy(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 = e1e_rphy(hw,			                            IGP01E1000_PHY_PORT_CONFIG,			                            &data);			if (ret_val)				goto out;			data |= IGP01E1000_PSCFR_SMART_SPEED;			ret_val = e1e_wphy(hw,			                             IGP01E1000_PHY_PORT_CONFIG,			                             data);			if (ret_val)				goto out;		} else if (phy->smart_speed == e1000_smart_speed_off) {			ret_val = e1e_rphy(hw,			                            IGP01E1000_PHY_PORT_CONFIG,			                            &data);			if (ret_val)				goto out;			data &= ~IGP01E1000_PSCFR_SMART_SPEED;			ret_val = e1e_wphy(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. **/static s32 e1000_reset_hw_82571(struct e1000_hw *hw){	u32 ctrl, extcnf_ctrl, ctrl_ext, icr;	s32 ret_val;	u16 i = 0;	/*	 * 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 = e1000e_disable_pcie_master(hw);	if (ret_val)		e_dbg("PCI-E Master disable polling has failed.\n");	e_dbg("Masking off all interrupts\n");	ew32(IMC, 0xffffffff);	ew32(RCTL, 0);	ew32(TCTL, E1000_TCTL_PSP);	e1e_flush();	msleep(10);	/*	 * Must acquire the MDIO ownership before MAC reset.	 * Ownership defaults to firmware after a reset.	 */	if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {		extcnf_ctrl = er32(EXTCNF_CTRL);		extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;		do {			ew32(EXTCNF_CTRL, extcnf_ctrl);			extcnf_ctrl = er32(EXTCNF_CTRL);			if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)				break;			extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;			msleep(2);			i++;		} while (i < MDIO_OWNERSHIP_TIMEOUT);	}	ctrl = er32(CTRL);	e_dbg("Issuing a global reset to MAC\n");	ew32(CTRL, ctrl | E1000_CTRL_RST);	if (hw->nvm.type == e1000_nvm_flash_hw) {		udelay(10);		ctrl_ext = er32(CTRL_EXT);		ctrl_ext |= E1000_CTRL_EXT_EE_RST;		ew32(CTRL_EXT, ctrl_ext);		e1e_flush();	}	ret_val = e1000e_get_auto_rd_done(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 || hw->mac.type == e1000_82574)		msleep(25);	/* Clear any pending interrupt events. */	ew32(IMC, 0xffffffff);	icr = er32(ICR);	if (!(e1000_check_alt_mac_addr_generic(hw)))		e1000e_set_laa_state_82571(hw, true);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;	e1000_initialize_hw_bits_82571(hw);	/* Initialize identification LED */	ret_val = mac->ops.id_led_init(hw);	if (ret_val) {		e_dbg("Error initializing identification LED\n");		/* This is not fatal and we should not stop init due to this */	}	/* Disabling VLAN filtering */	e_dbg("Initializing the IEEE VLAN\n");	e1000e_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 (e1000e_get_laa_state_82571(hw))		rar_count--;	e1000e_init_rx_addrs(hw, rar_count);	/* Zero out the Multicast HASH table */	e_dbg("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 = mac->ops.setup_link(hw);	/* Set the transmit descriptor write-back policy */	reg_data = er32(TXDCTL(0));	reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |	           E1000_TXDCTL_FULL_TX_DESC_WB |	           E1000_TXDCTL_COUNT_DESC;	ew32(TXDCTL(0), reg_data);	/* ...for both queues. */	if (mac->type != e1000_82573 && mac->type != e1000_82574) {		reg_data = er32(TXDCTL(1));		reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |		           E1000_TXDCTL_FULL_TX_DESC_WB |		           E1000_TXDCTL_COUNT_DESC;		ew32(TXDCTL(1), reg_data);	} else {		e1000e_enable_tx_pkt_filtering(hw);		reg_data = er32(GCR);		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;		ew32(GCR, reg_data);	}	/*	 * Clear all of the statistics registers (clear on read).  It is	 * important that we do this after we have tried to establish link	 * because the symbol error count will increment wildly if there	 * is no link.	 */	e1000_clear_hw_cntrs_82571(hw);	return ret_val;}/** *  e1000_initialize_hw_bits_82571 - Initialize hardware-dependent bits *  @hw: pointer to the HW structure * *  Initializes required hardware-dependent bits needed for normal operation. **/static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw){	u32 reg;	/* Transmit Descriptor Control 0 */	reg = er32(TXDCTL(0));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -