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

📄 82571.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 3 页
字号:
 * *  If e1000e_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;	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 = 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)		return ret_val;	/*	 * 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)		return ret_val;	/* 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)		return -E1000_ERR_NVM;	/* 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)		return -E1000_ERR_NVM;	return 0;}/** *  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 e1000e_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;	u32 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)) {		hw_dbg(hw, "nvm parameter(s) out of bounds\n");		return -E1000_ERR_NVM;	}	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;	}	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;	while (timeout) {		if (er32(EEMNGCTL) &		    E1000_NVM_CFG_DONE_PORT_0)			break;		msleep(1);		timeout--;	}	if (!timeout) {		hw_dbg(hw, "MNG configuration cycle has not completed.\n");		return -E1000_ERR_RESET;	}	return 0;}/** *  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;	u16 data;	ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data);	if (ret_val)		return ret_val;	if (active) {		data |= IGP02E1000_PM_D0_LPLU;		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);		if (ret_val)			return ret_val;		/* 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)			return ret_val;	} 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)				return ret_val;			data |= IGP01E1000_PSCFR_SMART_SPEED;			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,					   data);			if (ret_val)				return ret_val;		} else if (phy->smart_speed == e1000_smart_speed_off) {			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,					   &data);			if (ret_val)				return ret_val;			data &= ~IGP01E1000_PSCFR_SMART_SPEED;			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,					   data);			if (ret_val)				return ret_val;		}	}	return 0;}/** *  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;	u32 extcnf_ctrl;	u32 ctrl_ext;	u32 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)		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");	hw_dbg(hw, "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) {		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);	hw_dbg(hw, "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. */		return ret_val;	/*	 * 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)		msleep(25);	/* Clear any pending interrupt events. */	ew32(IMC, 0xffffffff);	icr = er32(ICR);	if (hw->mac.type == e1000_82571 &&		hw->dev_spec.e82571.alt_mac_addr_is_present)			e1000e_set_laa_state_82571(hw, true);	return 0;}/** *  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;	u16 rar_count = mac->rar_entry_count;	e1000_initialize_hw_bits_82571(hw);	/* Initialize identification LED */	ret_val = e1000e_id_led_init(hw);	if (ret_val) {		hw_dbg(hw, "Error initializing identification LED\n");		return ret_val;	}	/* Disabling VLAN filtering */	hw_dbg(hw, "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 */	hw_dbg(hw, "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_82571(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) {		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));	reg |= (1 << 22);	ew32(TXDCTL(0), reg);	/* Transmit Descriptor Control 1 */	reg = er32(TXDCTL(1));	reg |= (1 << 22);	ew32(TXDCTL(1), reg);	/* Transmit Arbitration Control 0 */	reg = er32(TARC(0));	reg &= ~(0xF << 27); /* 30:27 */	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26);		break;	default:		break;	}	ew32(TARC(0), reg);	/* Transmit Arbitration Control 1 */	reg = er32(TARC(1));	switch (hw->mac.type) {	case e1000_82571:	case e1000_82572:		reg &= ~((1 << 29) | (1 << 30));		reg |= (1 << 22) | (1 << 24) | (1 << 25) | (1 << 26);		if (er32(TCTL) & E1000_TCTL_MULR)			reg &= ~(1 << 28);		else			reg |= (1 << 28);		ew32(TARC(1), reg);		break;	default:		break;

⌨️ 快捷键说明

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