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

📄 lib.c

📁 grub源码分析文档
💻 C
📖 第 1 页 / 共 5 页
字号:
	ew32(LEDCTL, ledctl_blink);	return 0;}/** *  e1000e_led_on_generic - Turn LED on *  @hw: pointer to the HW structure * *  Turn LED on. **/s32 e1000e_led_on_generic(struct e1000_hw *hw){	u32 ctrl;	switch (hw->phy.media_type) {	case e1000_media_type_fiber:		ctrl = er32(CTRL);		ctrl &= ~E1000_CTRL_SWDPIN0;		ctrl |= E1000_CTRL_SWDPIO0;		ew32(CTRL, ctrl);		break;	case e1000_media_type_copper:		ew32(LEDCTL, hw->mac.ledctl_mode2);		break;	default:		break;	}	return 0;}/** *  e1000e_led_off_generic - Turn LED off *  @hw: pointer to the HW structure * *  Turn LED off. **/s32 e1000e_led_off_generic(struct e1000_hw *hw){	u32 ctrl;	switch (hw->phy.media_type) {	case e1000_media_type_fiber:		ctrl = er32(CTRL);		ctrl |= E1000_CTRL_SWDPIN0;		ctrl |= E1000_CTRL_SWDPIO0;		ew32(CTRL, ctrl);		break;	case e1000_media_type_copper:		ew32(LEDCTL, hw->mac.ledctl_mode1);		break;	default:		break;	}	return 0;}/** *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities *  @hw: pointer to the HW structure *  @no_snoop: bitmap of snoop events * *  Set the PCI-express register to snoop for events enabled in 'no_snoop'. **/void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop){	u32 gcr;	if (no_snoop) {		gcr = er32(GCR);		gcr &= ~(PCIE_NO_SNOOP_ALL);		gcr |= no_snoop;		ew32(GCR, gcr);	}}/** *  e1000e_disable_pcie_master - Disables PCI-express master access *  @hw: pointer to the HW structure * *  Returns 0 if successful, else returns -10 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused *  the master requests to be disabled. * *  Disables PCI-Express master access and verifies there are no pending *  requests. **/s32 e1000e_disable_pcie_master(struct e1000_hw *hw){	u32 ctrl;	s32 timeout = MASTER_DISABLE_TIMEOUT;	ctrl = er32(CTRL);	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;	ew32(CTRL, ctrl);	while (timeout) {		if (!(er32(STATUS) &		      E1000_STATUS_GIO_MASTER_ENABLE))			break;		udelay(100);		timeout--;	}	if (!timeout) {		hw_dbg(hw, "Master requests are pending.\n");		return -E1000_ERR_MASTER_REQUESTS_PENDING;	}	return 0;}/** *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing *  @hw: pointer to the HW structure * *  Reset the Adaptive Interframe Spacing throttle to default values. **/void e1000e_reset_adaptive(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	mac->current_ifs_val = 0;	mac->ifs_min_val = IFS_MIN;	mac->ifs_max_val = IFS_MAX;	mac->ifs_step_size = IFS_STEP;	mac->ifs_ratio = IFS_RATIO;	mac->in_ifs_mode = 0;	ew32(AIT, 0);}/** *  e1000e_update_adaptive - Update Adaptive Interframe Spacing *  @hw: pointer to the HW structure * *  Update the Adaptive Interframe Spacing Throttle value based on the *  time between transmitted packets and time between collisions. **/void e1000e_update_adaptive(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {		if (mac->tx_packet_delta > MIN_NUM_XMITS) {			mac->in_ifs_mode = 1;			if (mac->current_ifs_val < mac->ifs_max_val) {				if (!mac->current_ifs_val)					mac->current_ifs_val = mac->ifs_min_val;				else					mac->current_ifs_val +=						mac->ifs_step_size;				ew32(AIT, mac->current_ifs_val);			}		}	} else {		if (mac->in_ifs_mode &&		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {			mac->current_ifs_val = 0;			mac->in_ifs_mode = 0;			ew32(AIT, 0);		}	}}/** *  e1000_raise_eec_clk - Raise EEPROM clock *  @hw: pointer to the HW structure *  @eecd: pointer to the EEPROM * *  Enable/Raise the EEPROM clock bit. **/static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd){	*eecd = *eecd | E1000_EECD_SK;	ew32(EECD, *eecd);	e1e_flush();	udelay(hw->nvm.delay_usec);}/** *  e1000_lower_eec_clk - Lower EEPROM clock *  @hw: pointer to the HW structure *  @eecd: pointer to the EEPROM * *  Clear/Lower the EEPROM clock bit. **/static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd){	*eecd = *eecd & ~E1000_EECD_SK;	ew32(EECD, *eecd);	e1e_flush();	udelay(hw->nvm.delay_usec);}/** *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM *  @hw: pointer to the HW structure *  @data: data to send to the EEPROM *  @count: number of bits to shift out * *  We need to shift 'count' bits out to the EEPROM.  So, the value in the *  "data" parameter will be shifted out to the EEPROM one bit at a time. *  In order to do this, "data" must be broken down into bits. **/static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 eecd = er32(EECD);	u32 mask;	mask = 0x01 << (count - 1);	if (nvm->type == e1000_nvm_eeprom_spi)		eecd |= E1000_EECD_DO;	do {		eecd &= ~E1000_EECD_DI;		if (data & mask)			eecd |= E1000_EECD_DI;		ew32(EECD, eecd);		e1e_flush();		udelay(nvm->delay_usec);		e1000_raise_eec_clk(hw, &eecd);		e1000_lower_eec_clk(hw, &eecd);		mask >>= 1;	} while (mask);	eecd &= ~E1000_EECD_DI;	ew32(EECD, eecd);}/** *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM *  @hw: pointer to the HW structure *  @count: number of bits to shift in * *  In order to read a register from the EEPROM, we need to shift 'count' bits *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to *  the EEPROM (setting the SK bit), and then reading the value of the data out *  "DO" bit.  During this "shifting in" process the data in "DI" bit should *  always be clear. **/static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count){	u32 eecd;	u32 i;	u16 data;	eecd = er32(EECD);	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);	data = 0;	for (i = 0; i < count; i++) {		data <<= 1;		e1000_raise_eec_clk(hw, &eecd);		eecd = er32(EECD);		eecd &= ~E1000_EECD_DI;		if (eecd & E1000_EECD_DO)			data |= 1;		e1000_lower_eec_clk(hw, &eecd);	}	return data;}/** *  e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion *  @hw: pointer to the HW structure *  @ee_reg: EEPROM flag for polling * *  Polls the EEPROM status bit for either read or write completion based *  upon the value of 'ee_reg'. **/s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg){	u32 attempts = 100000;	u32 i, reg = 0;	for (i = 0; i < attempts; i++) {		if (ee_reg == E1000_NVM_POLL_READ)			reg = er32(EERD);		else			reg = er32(EEWR);		if (reg & E1000_NVM_RW_REG_DONE)			return 0;		udelay(5);	}	return -E1000_ERR_NVM;}/** *  e1000e_acquire_nvm - Generic request for access to EEPROM *  @hw: pointer to the HW structure * *  Set the EEPROM access request bit and wait for EEPROM access grant bit. *  Return successful if access grant bit set, else clear the request for *  EEPROM access and return -E1000_ERR_NVM (-1). **/s32 e1000e_acquire_nvm(struct e1000_hw *hw){	u32 eecd = er32(EECD);	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;	ew32(EECD, eecd | E1000_EECD_REQ);	eecd = er32(EECD);	while (timeout) {		if (eecd & E1000_EECD_GNT)			break;		udelay(5);		eecd = er32(EECD);		timeout--;	}	if (!timeout) {		eecd &= ~E1000_EECD_REQ;		ew32(EECD, eecd);		hw_dbg(hw, "Could not acquire NVM grant\n");		return -E1000_ERR_NVM;	}	return 0;}/** *  e1000_standby_nvm - Return EEPROM to standby state *  @hw: pointer to the HW structure * *  Return the EEPROM to a standby state. **/static void e1000_standby_nvm(struct e1000_hw *hw){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 eecd = er32(EECD);	if (nvm->type == e1000_nvm_eeprom_spi) {		/* Toggle CS to flush commands */		eecd |= E1000_EECD_CS;		ew32(EECD, eecd);		e1e_flush();		udelay(nvm->delay_usec);		eecd &= ~E1000_EECD_CS;		ew32(EECD, eecd);		e1e_flush();		udelay(nvm->delay_usec);	}}/** *  e1000_stop_nvm - Terminate EEPROM command *  @hw: pointer to the HW structure * *  Terminates the current command by inverting the EEPROM's chip select pin. **/static void e1000_stop_nvm(struct e1000_hw *hw){	u32 eecd;	eecd = er32(EECD);	if (hw->nvm.type == e1000_nvm_eeprom_spi) {		/* Pull CS high */		eecd |= E1000_EECD_CS;		e1000_lower_eec_clk(hw, &eecd);	}}/** *  e1000e_release_nvm - Release exclusive access to EEPROM *  @hw: pointer to the HW structure * *  Stop any current commands to the EEPROM and clear the EEPROM request bit. **/void e1000e_release_nvm(struct e1000_hw *hw){	u32 eecd;	e1000_stop_nvm(hw);	eecd = er32(EECD);	eecd &= ~E1000_EECD_REQ;	ew32(EECD, eecd);}/** *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write *  @hw: pointer to the HW structure * *  Setups the EEPROM for reading and writing. **/static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 eecd = er32(EECD);	u16 timeout = 0;	u8 spi_stat_reg;	if (nvm->type == e1000_nvm_eeprom_spi) {		/* Clear SK and CS */		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);		ew32(EECD, eecd);		udelay(1);		timeout = NVM_MAX_RETRY_SPI;		/*		 * Read "Status Register" repeatedly until the LSB is cleared.		 * The EEPROM will signal that the command has been completed		 * by clearing bit 0 of the internal status register.  If it's		 * not cleared within 'timeout', then error out.		 */		while (timeout) {			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,						 hw->nvm.opcode_bits);			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))				break;			udelay(5);			e1000_standby_nvm(hw);			timeout--;		}		if (!timeout) {			hw_dbg(hw, "SPI NVM Status error\n");			return -E1000_ERR_NVM;		}	}	return 0;}/** *  e1000e_read_nvm_eerd - Reads EEPROM using EERD register *  @hw: pointer to the HW structure *  @offset: offset of word in the EEPROM to read *  @words: number of words to read *  @data: word read from the EEPROM * *  Reads a 16 bit word from the EEPROM using the EERD register. **/s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data){	struct e1000_nvm_info *nvm = &hw->nvm;	u32 i, eerd = 0;	s32 ret_val = 0;	/*	 * A check for invalid values:  offset too large, too many words,	 * too many words for the offset, 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++) {		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +		       E1000_NVM_RW_REG_START;		ew32(EERD, eerd);		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);		if (ret_val)			break;		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);	}	return ret_val;}

⌨️ 快捷键说明

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