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

📄 ixgb_ee.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************    Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.    This program is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by the Free   Software Foundation; either version 2 of the License, or (at your option)   any later version.    This program is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   more details.    You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  Linux NICS <linux.nics@intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************/#include "ixgb_hw.h"#include "ixgb_ee.h"/* Local prototypes */static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);static void ixgb_shift_out_bits(struct ixgb_hw *hw,				uint16_t data,				uint16_t count);static void ixgb_standby_eeprom(struct ixgb_hw *hw);static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);static void ixgb_cleanup_eeprom(struct ixgb_hw *hw);/****************************************************************************** * Raises the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd_reg - EECD's current value *****************************************************************************/static voidixgb_raise_clock(struct ixgb_hw *hw,		  uint32_t *eecd_reg){	/* Raise the clock input to the EEPROM (by setting the SK bit), and then	 *  wait 50 microseconds.	 */	*eecd_reg = *eecd_reg | IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, *eecd_reg);	udelay(50);	return;}/****************************************************************************** * Lowers the EEPROM's clock input. * * hw - Struct containing variables accessed by shared code * eecd_reg - EECD's current value *****************************************************************************/static voidixgb_lower_clock(struct ixgb_hw *hw,		  uint32_t *eecd_reg){	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then	 * wait 50 microseconds.	 */	*eecd_reg = *eecd_reg & ~IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, *eecd_reg);	udelay(50);	return;}/****************************************************************************** * Shift data bits out to the EEPROM. * * hw - Struct containing variables accessed by shared code * data - data to send to the EEPROM * count - number of bits to shift out *****************************************************************************/static voidixgb_shift_out_bits(struct ixgb_hw *hw,					 uint16_t data,					 uint16_t count){	uint32_t eecd_reg;	uint32_t mask;	/* We need to shift "count" bits out to the EEPROM. So, 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.	 */	mask = 0x01 << (count - 1);	eecd_reg = IXGB_READ_REG(hw, EECD);	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);	do {		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",		 * and then raising and then lowering the clock (the SK bit controls		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM		 * by setting "DI" to "0" and then raising and then lowering the clock.		 */		eecd_reg &= ~IXGB_EECD_DI;		if(data & mask)			eecd_reg |= IXGB_EECD_DI;		IXGB_WRITE_REG(hw, EECD, eecd_reg);		udelay(50);		ixgb_raise_clock(hw, &eecd_reg);		ixgb_lower_clock(hw, &eecd_reg);		mask = mask >> 1;	} while(mask);	/* We leave the "DI" bit set to "0" when we leave this routine. */	eecd_reg &= ~IXGB_EECD_DI;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	return;}/****************************************************************************** * Shift data bits in from the EEPROM * * hw - Struct containing variables accessed by shared code *****************************************************************************/static uint16_tixgb_shift_in_bits(struct ixgb_hw *hw){	uint32_t eecd_reg;	uint32_t i;	uint16_t data;	/* In order to read a register from the EEPROM, we need to shift 16 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 "DO"	 * bit.  During this "shifting in" process the "DI" bit should always be	 * clear..	 */	eecd_reg = IXGB_READ_REG(hw, EECD);	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);	data = 0;	for(i = 0; i < 16; i++) {		data = data << 1;		ixgb_raise_clock(hw, &eecd_reg);		eecd_reg = IXGB_READ_REG(hw, EECD);		eecd_reg &= ~(IXGB_EECD_DI);		if(eecd_reg & IXGB_EECD_DO)			data |= 1;		ixgb_lower_clock(hw, &eecd_reg);	}	return data;}/****************************************************************************** * Prepares EEPROM for access * * hw - Struct containing variables accessed by shared code * * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This * function should be called before issuing a command to the EEPROM. *****************************************************************************/static voidixgb_setup_eeprom(struct ixgb_hw *hw){	uint32_t eecd_reg;	eecd_reg = IXGB_READ_REG(hw, EECD);	/*  Clear SK and DI  */	eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI);	IXGB_WRITE_REG(hw, EECD, eecd_reg);	/*  Set CS  */	eecd_reg |= IXGB_EECD_CS;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	return;}/****************************************************************************** * Returns EEPROM to a "standby" state * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voidixgb_standby_eeprom(struct ixgb_hw *hw){	uint32_t eecd_reg;	eecd_reg = IXGB_READ_REG(hw, EECD);	/*  Deselct EEPROM  */	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	/*  Clock high  */	eecd_reg |= IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	/*  Select EEPROM  */	eecd_reg |= IXGB_EECD_CS;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	/*  Clock low  */	eecd_reg &= ~IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	return;}/****************************************************************************** * Raises then lowers the EEPROM's clock pin * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voidixgb_clock_eeprom(struct ixgb_hw *hw){	uint32_t eecd_reg;	eecd_reg = IXGB_READ_REG(hw, EECD);	/*  Rising edge of clock  */	eecd_reg |= IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	/*  Falling edge of clock  */	eecd_reg &= ~IXGB_EECD_SK;	IXGB_WRITE_REG(hw, EECD, eecd_reg);	udelay(50);	return;}/****************************************************************************** * Terminates a command by lowering the EEPROM's chip select pin * * hw - Struct containing variables accessed by shared code *****************************************************************************/static voidixgb_cleanup_eeprom(struct ixgb_hw *hw){	uint32_t eecd_reg;	eecd_reg = IXGB_READ_REG(hw, EECD);	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI);	IXGB_WRITE_REG(hw, EECD, eecd_reg);	ixgb_clock_eeprom(hw);	return;}/****************************************************************************** * Waits for the EEPROM to finish the current command. * * hw - Struct containing variables accessed by shared code * * The command is done when the EEPROM's data out pin goes high. * * Returns: *      TRUE: EEPROM data pin is high before timeout. *      FALSE:  Time expired. *****************************************************************************/static boolean_tixgb_wait_eeprom_command(struct ixgb_hw *hw){	uint32_t eecd_reg;	uint32_t i;	/* Toggle the CS line.  This in effect tells to EEPROM to actually execute	 * the command in question.	 */	ixgb_standby_eeprom(hw);	/* Now read DO repeatedly until is high (equal to '1').  The EEEPROM will	 * signal that the command has been completed by raising the DO signal.	 * If DO does not go high in 10 milliseconds, then error out.	 */	for(i = 0; i < 200; i++) {		eecd_reg = IXGB_READ_REG(hw, EECD);		if(eecd_reg & IXGB_EECD_DO)			return (TRUE);

⌨️ 快捷键说明

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