diff options
| -rw-r--r-- | drivers/net/e1000.c | 3096 | ||||
| -rw-r--r-- | drivers/net/e1000.h | 837 | ||||
| -rw-r--r-- | include/net.h | 2 | ||||
| -rw-r--r-- | include/pci_ids.h | 22 | ||||
| -rw-r--r-- | net/Makefile | 2 | ||||
| -rw-r--r-- | net/bootp.c | 81 | ||||
| -rw-r--r-- | net/eth.c | 56 | ||||
| -rw-r--r-- | net/net.c | 80 | ||||
| -rw-r--r-- | net/nfs.c | 42 | ||||
| -rw-r--r-- | net/rarp.c | 4 | ||||
| -rw-r--r-- | net/sntp.c | 6 | ||||
| -rw-r--r-- | net/tftp.c | 21 | 
12 files changed, 3564 insertions, 685 deletions
| diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index a52749d78..e3c6cea44 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -51,7 +51,7 @@ tested on both gig copper and gig fiber boards  #define bus_to_phys(devno, a)	pci_mem_to_phys(devno, a)  #define mdelay(n)	udelay((n)*1000) -#define E1000_DEFAULT_PBA    0x00000030 +#define E1000_DEFAULT_PBA    0x000a0026  /* NIC specific static variables go here */ @@ -82,6 +82,28 @@ static struct pci_device_id supported[] = {  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},  	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF}, +	/* E1000 PCIe card */ +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_COPPER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_FIBER      }, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES     }, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_COPPER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_FIBER}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI_SERDES}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82572EI}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573E_IAMT}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82573L}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT}, +	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT},  	{}  }; @@ -95,16 +117,23 @@ static int e1000_config_mac_to_phy(struct e1000_hw *hw);  static int e1000_config_fc_after_link_up(struct e1000_hw *hw);  static int e1000_check_for_link(struct eth_device *nic);  static int e1000_wait_autoneg(struct e1000_hw *hw); -static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, +static int e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed,  				       uint16_t * duplex);  static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,  			      uint16_t * phy_data);  static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr,  			       uint16_t phy_data); -static void e1000_phy_hw_reset(struct e1000_hw *hw); +static int32_t e1000_phy_hw_reset(struct e1000_hw *hw);  static int e1000_phy_reset(struct e1000_hw *hw);  static int e1000_detect_gig_phy(struct e1000_hw *hw); +static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, +		uint16_t words, +		uint16_t *data); +static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); +static void e1000_set_media_type(struct e1000_hw *hw); +static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); +static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);  #define E1000_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + E1000_##reg)))  #define E1000_READ_REG(a, reg) (readl((a)->hw_addr + E1000_##reg))  #define E1000_WRITE_REG_ARRAY(a, reg, offset, value) (\ @@ -204,17 +233,17 @@ e1000_shift_out_ee_bits(struct e1000_hw *hw, uint16_t data, uint16_t count)   * hw - Struct containing variables accessed by shared code   *****************************************************************************/  static uint16_t -e1000_shift_in_ee_bits(struct e1000_hw *hw) +e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count)  {  	uint32_t eecd;  	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.. +	/* 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 "DO" bit.  During this "shifting in" process the +	 * "DI" bit should always be clear.  	 */  	eecd = E1000_READ_REG(hw, EECD); @@ -222,7 +251,7 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)  	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);  	data = 0; -	for (i = 0; i < 16; i++) { +	for (i = 0; i < count; i++) {  		data = data << 1;  		e1000_raise_ee_clk(hw, &eecd); @@ -239,213 +268,600 @@ e1000_shift_in_ee_bits(struct e1000_hw *hw)  }  /****************************************************************************** - * Prepares EEPROM for access + * Returns EEPROM to a "standby" state   *   * 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 void -e1000_setup_eeprom(struct e1000_hw *hw) +e1000_standby_eeprom(struct e1000_hw *hw)  { +	struct e1000_eeprom_info *eeprom = &hw->eeprom;  	uint32_t eecd;  	eecd = E1000_READ_REG(hw, EECD); -	/* Clear SK and DI */ -	eecd &= ~(E1000_EECD_SK | E1000_EECD_DI); -	E1000_WRITE_REG(hw, EECD, eecd); +	if (eeprom->type == e1000_eeprom_microwire) { +		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); -	/* Set CS */ -	eecd |= E1000_EECD_CS; -	E1000_WRITE_REG(hw, EECD, eecd); +		/* Clock high */ +		eecd |= E1000_EECD_SK; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); + +		/* Select EEPROM */ +		eecd |= E1000_EECD_CS; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); + +		/* Clock low */ +		eecd &= ~E1000_EECD_SK; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); +	} else if (eeprom->type == e1000_eeprom_spi) { +		/* Toggle CS to flush commands */ +		eecd |= E1000_EECD_CS; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); +		eecd &= ~E1000_EECD_CS; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(eeprom->delay_usec); +	} +} + +/*************************************************************************** +* Description:     Determines if the onboard NVM is FLASH or EEPROM. +* +* hw - Struct containing variables accessed by shared code +****************************************************************************/ +static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) +{ +	uint32_t eecd = 0; + +	DEBUGFUNC(); + +	if (hw->mac_type == e1000_ich8lan) +		return FALSE; + +	if (hw->mac_type == e1000_82573) { +		eecd = E1000_READ_REG(hw, EECD); + +		/* Isolate bits 15 & 16 */ +		eecd = ((eecd >> 15) & 0x03); + +		/* If both bits are set, device is Flash type */ +		if (eecd == 0x03) +			return FALSE; +	} +	return TRUE;  }  /****************************************************************************** - * Returns EEPROM to a "standby" state + * 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 void -e1000_standby_eeprom(struct e1000_hw *hw) +static int32_t +e1000_acquire_eeprom(struct e1000_hw *hw)  { -	uint32_t eecd; +	struct e1000_eeprom_info *eeprom = &hw->eeprom; +	uint32_t eecd, i = 0; +	DEBUGOUT(); + +	if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM)) +		return -E1000_ERR_SWFW_SYNC;  	eecd = E1000_READ_REG(hw, EECD); -	/* Deselct EEPROM */ -	eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); -	E1000_WRITE_REG(hw, EECD, eecd); -	E1000_WRITE_FLUSH(hw); -	udelay(50); +	if (hw->mac_type != e1000_82573) { +		/* Request EEPROM Access */ +		if (hw->mac_type > e1000_82544) { +			eecd |= E1000_EECD_REQ; +			E1000_WRITE_REG(hw, EECD, eecd); +			eecd = E1000_READ_REG(hw, EECD); +			while ((!(eecd & E1000_EECD_GNT)) && +				(i < E1000_EEPROM_GRANT_ATTEMPTS)) { +				i++; +				udelay(5); +				eecd = E1000_READ_REG(hw, EECD); +			} +			if (!(eecd & E1000_EECD_GNT)) { +				eecd &= ~E1000_EECD_REQ; +				E1000_WRITE_REG(hw, EECD, eecd); +				DEBUGOUT("Could not acquire EEPROM grant\n"); +				return -E1000_ERR_EEPROM; +			} +		} +	} -	/* Clock high */ -	eecd |= E1000_EECD_SK; -	E1000_WRITE_REG(hw, EECD, eecd); -	E1000_WRITE_FLUSH(hw); -	udelay(50); +	/* Setup EEPROM for Read/Write */ -	/* Select EEPROM */ -	eecd |= E1000_EECD_CS; -	E1000_WRITE_REG(hw, EECD, eecd); -	E1000_WRITE_FLUSH(hw); -	udelay(50); +	if (eeprom->type == e1000_eeprom_microwire) { +		/* Clear SK and DI */ +		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK); +		E1000_WRITE_REG(hw, EECD, eecd); -	/* Clock low */ -	eecd &= ~E1000_EECD_SK; -	E1000_WRITE_REG(hw, EECD, eecd); -	E1000_WRITE_FLUSH(hw); -	udelay(50); +		/* Set CS */ +		eecd |= E1000_EECD_CS; +		E1000_WRITE_REG(hw, EECD, eecd); +	} else if (eeprom->type == e1000_eeprom_spi) { +		/* Clear SK and CS */ +		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); +		E1000_WRITE_REG(hw, EECD, eecd); +		udelay(1); +	} + +	return E1000_SUCCESS;  }  /****************************************************************************** - * Reads a 16 bit word from the EEPROM. + * Sets up eeprom variables in the hw struct.  Must be called after mac_type + * is configured.  Additionally, if this is ICH8, the flash controller GbE + * registers must be mapped, or this will crash.   *   * hw - Struct containing variables accessed by shared code - * offset - offset of  word in the EEPROM to read - * data - word read from the EEPROM   *****************************************************************************/ -static int -e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t * data) +static int32_t e1000_init_eeprom_params(struct e1000_hw *hw)  { -	uint32_t eecd; -	uint32_t i = 0; -	int large_eeprom = FALSE; +	struct e1000_eeprom_info *eeprom = &hw->eeprom; +	uint32_t eecd = E1000_READ_REG(hw, EECD); +	int32_t ret_val = E1000_SUCCESS; +	uint16_t eeprom_size; -	/* Request EEPROM Access */ -	if (hw->mac_type > e1000_82544) { -		eecd = E1000_READ_REG(hw, EECD); -		if (eecd & E1000_EECD_SIZE) -			large_eeprom = TRUE; -		eecd |= E1000_EECD_REQ; -		E1000_WRITE_REG(hw, EECD, eecd); -		eecd = E1000_READ_REG(hw, EECD); -		while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) { -			i++; -			udelay(10); -			eecd = E1000_READ_REG(hw, EECD); +	DEBUGOUT(); + +	switch (hw->mac_type) { +	case e1000_82542_rev2_0: +	case e1000_82542_rev2_1: +	case e1000_82543: +	case e1000_82544: +		eeprom->type = e1000_eeprom_microwire; +		eeprom->word_size = 64; +		eeprom->opcode_bits = 3; +		eeprom->address_bits = 6; +		eeprom->delay_usec = 50; +		eeprom->use_eerd = FALSE; +		eeprom->use_eewr = FALSE; +	break; +	case e1000_82540: +	case e1000_82545: +	case e1000_82545_rev_3: +	case e1000_82546: +	case e1000_82546_rev_3: +		eeprom->type = e1000_eeprom_microwire; +		eeprom->opcode_bits = 3; +		eeprom->delay_usec = 50; +		if (eecd & E1000_EECD_SIZE) { +			eeprom->word_size = 256; +			eeprom->address_bits = 8; +		} else { +			eeprom->word_size = 64; +			eeprom->address_bits = 6; +		} +		eeprom->use_eerd = FALSE; +		eeprom->use_eewr = FALSE; +		break; +	case e1000_82541: +	case e1000_82541_rev_2: +	case e1000_82547: +	case e1000_82547_rev_2: +		if (eecd & E1000_EECD_TYPE) { +			eeprom->type = e1000_eeprom_spi; +			eeprom->opcode_bits = 8; +			eeprom->delay_usec = 1; +			if (eecd & E1000_EECD_ADDR_BITS) { +				eeprom->page_size = 32; +				eeprom->address_bits = 16; +			} else { +				eeprom->page_size = 8; +				eeprom->address_bits = 8; +			} +		} else { +			eeprom->type = e1000_eeprom_microwire; +			eeprom->opcode_bits = 3; +			eeprom->delay_usec = 50; +			if (eecd & E1000_EECD_ADDR_BITS) { +				eeprom->word_size = 256; +				eeprom->address_bits = 8; +			} else { +				eeprom->word_size = 64; +				eeprom->address_bits = 6; +			}  		} -		if (!(eecd & E1000_EECD_GNT)) { -			eecd &= ~E1000_EECD_REQ; +		eeprom->use_eerd = FALSE; +		eeprom->use_eewr = FALSE; +		break; +	case e1000_82571: +	case e1000_82572: +		eeprom->type = e1000_eeprom_spi; +		eeprom->opcode_bits = 8; +		eeprom->delay_usec = 1; +		if (eecd & E1000_EECD_ADDR_BITS) { +			eeprom->page_size = 32; +			eeprom->address_bits = 16; +		} else { +			eeprom->page_size = 8; +			eeprom->address_bits = 8; +		} +		eeprom->use_eerd = FALSE; +		eeprom->use_eewr = FALSE; +		break; +	case e1000_82573: +		eeprom->type = e1000_eeprom_spi; +		eeprom->opcode_bits = 8; +		eeprom->delay_usec = 1; +		if (eecd & E1000_EECD_ADDR_BITS) { +			eeprom->page_size = 32; +			eeprom->address_bits = 16; +		} else { +			eeprom->page_size = 8; +			eeprom->address_bits = 8; +		} +		eeprom->use_eerd = TRUE; +		eeprom->use_eewr = TRUE; +		if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) { +			eeprom->type = e1000_eeprom_flash; +			eeprom->word_size = 2048; + +		/* Ensure that the Autonomous FLASH update bit is cleared due to +		 * Flash update issue on parts which use a FLASH for NVM. */ +			eecd &= ~E1000_EECD_AUPDEN;  			E1000_WRITE_REG(hw, EECD, eecd); -			DEBUGOUT("Could not acquire EEPROM grant\n"); -			return -E1000_ERR_EEPROM;  		} -	} +		break; +	case e1000_80003es2lan: +		eeprom->type = e1000_eeprom_spi; +		eeprom->opcode_bits = 8; +		eeprom->delay_usec = 1; +		if (eecd & E1000_EECD_ADDR_BITS) { +			eeprom->page_size = 32; +			eeprom->address_bits = 16; +		} else { +			eeprom->page_size = 8; +			eeprom->address_bits = 8; +		} +		eeprom->use_eerd = TRUE; +		eeprom->use_eewr = FALSE; +		break; -	/*  Prepare the EEPROM for reading  */ -	e1000_setup_eeprom(hw); +	/* ich8lan does not support currently. if needed, please +	 * add corresponding code and functions. +	 */ +#if 0 +	case e1000_ich8lan: +		{ +		int32_t  i = 0; -	/*  Send the READ command (opcode + addr)  */ -	e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE, 3); -	e1000_shift_out_ee_bits(hw, offset, (large_eeprom) ? 8 : 6); +		eeprom->type = e1000_eeprom_ich8; +		eeprom->use_eerd = FALSE; +		eeprom->use_eewr = FALSE; +		eeprom->word_size = E1000_SHADOW_RAM_WORDS; +		uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw, +				ICH_FLASH_GFPREG); +		/* Zero the shadow RAM structure. But don't load it from NVM +		 * so as to save time for driver init */ +		if (hw->eeprom_shadow_ram != NULL) { +			for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { +				hw->eeprom_shadow_ram[i].modified = FALSE; +				hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF; +			} +		} -	/* Read the data */ -	*data = e1000_shift_in_ee_bits(hw); +		hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) * +				ICH_FLASH_SECTOR_SIZE; -	/* End this read operation */ -	e1000_standby_eeprom(hw); +		hw->flash_bank_size = ((flash_size >> 16) +				& ICH_GFPREG_BASE_MASK) + 1; +		hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK); -	/* Stop requesting EEPROM access */ -	if (hw->mac_type > e1000_82544) { -		eecd = E1000_READ_REG(hw, EECD); -		eecd &= ~E1000_EECD_REQ; -		E1000_WRITE_REG(hw, EECD, eecd); +		hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE; + +		hw->flash_bank_size /= 2 * sizeof(uint16_t); +		break; +		} +#endif +	default: +		break;  	} -	return 0; +	if (eeprom->type == e1000_eeprom_spi) { +		/* eeprom_size will be an enum [0..8] that maps +		 * to eeprom sizes 128B to +		 * 32KB (incremented by powers of 2). +		 */ +		if (hw->mac_type <= e1000_82547_rev_2) { +			/* Set to default value for initial eeprom read. */ +			eeprom->word_size = 64; +			ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, +					&eeprom_size); +			if (ret_val) +				return ret_val; +			eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) +				>> EEPROM_SIZE_SHIFT; +			/* 256B eeprom size was not supported in earlier +			 * hardware, so we bump eeprom_size up one to +			 * ensure that "1" (which maps to 256B) is never +			 * the result used in the shifting logic below. */ +			if (eeprom_size) +				eeprom_size++; +		} else { +			eeprom_size = (uint16_t)((eecd & +				E1000_EECD_SIZE_EX_MASK) >> +				E1000_EECD_SIZE_EX_SHIFT); +		} + +		eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT); +	} +	return ret_val;  } -#if 0 -static void -e1000_eeprom_cleanup(struct e1000_hw *hw) +/****************************************************************************** + * Polls the status bit (bit 1) of the EERD to determine when the read is done. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +static int32_t +e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)  { -	uint32_t eecd; +	uint32_t attempts = 100000; +	uint32_t i, reg = 0; +	int32_t done = E1000_ERR_EEPROM; -	eecd = E1000_READ_REG(hw, EECD); -	eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); -	E1000_WRITE_REG(hw, EECD, eecd); -	e1000_raise_ee_clk(hw, &eecd); -	e1000_lower_ee_clk(hw, &eecd); +	for (i = 0; i < attempts; i++) { +		if (eerd == E1000_EEPROM_POLL_READ) +			reg = E1000_READ_REG(hw, EERD); +		else +			reg = E1000_READ_REG(hw, EEWR); + +		if (reg & E1000_EEPROM_RW_REG_DONE) { +			done = E1000_SUCCESS; +			break; +		} +		udelay(5); +	} + +	return done;  } -static uint16_t -e1000_wait_eeprom_done(struct e1000_hw *hw) +/****************************************************************************** + * Reads a 16 bit word from the EEPROM using the EERD register. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of  word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read + *****************************************************************************/ +static int32_t +e1000_read_eeprom_eerd(struct e1000_hw *hw, +			uint16_t offset, +			uint16_t words, +			uint16_t *data)  { -	uint32_t eecd; -	uint32_t i; +	uint32_t i, eerd = 0; +	int32_t error = 0; + +	for (i = 0; i < words; i++) { +		eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + +			E1000_EEPROM_RW_REG_START; + +		E1000_WRITE_REG(hw, EERD, eerd); +		error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); + +		if (error) +			break; +		data[i] = (E1000_READ_REG(hw, EERD) >> +				E1000_EEPROM_RW_REG_DATA); -	e1000_standby_eeprom(hw); -	for (i = 0; i < 200; i++) { -		eecd = E1000_READ_REG(hw, EECD); -		if (eecd & E1000_EECD_DO) -			return (TRUE); -		udelay(5);  	} -	return (FALSE); + +	return error;  } -static int -e1000_write_eeprom(struct e1000_hw *hw, uint16_t Reg, uint16_t Data) +static void +e1000_release_eeprom(struct e1000_hw *hw)  {  	uint32_t eecd; -	int large_eeprom = FALSE; -	int i = 0; -	/* Request EEPROM Access */ -	if (hw->mac_type > e1000_82544) { -		eecd = E1000_READ_REG(hw, EECD); -		if (eecd & E1000_EECD_SIZE) -			large_eeprom = TRUE; -		eecd |= E1000_EECD_REQ; +	DEBUGFUNC(); + +	eecd = E1000_READ_REG(hw, EECD); + +	if (hw->eeprom.type == e1000_eeprom_spi) { +		eecd |= E1000_EECD_CS;  /* Pull CS high */ +		eecd &= ~E1000_EECD_SK; /* Lower SCK */ +  		E1000_WRITE_REG(hw, EECD, eecd); -		eecd = E1000_READ_REG(hw, EECD); -		while ((!(eecd & E1000_EECD_GNT)) && (i < 100)) { -			i++; -			udelay(5); -			eecd = E1000_READ_REG(hw, EECD); -		} -		if (!(eecd & E1000_EECD_GNT)) { -			eecd &= ~E1000_EECD_REQ; -			E1000_WRITE_REG(hw, EECD, eecd); -			DEBUGOUT("Could not acquire EEPROM grant\n"); -			return FALSE; -		} -	} -	e1000_setup_eeprom(hw); -	e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5); -	e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4); -	e1000_standby_eeprom(hw); -	e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3); -	e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 8 : 6); -	e1000_shift_out_ee_bits(hw, Data, 16); -	if (!e1000_wait_eeprom_done(hw)) { -		return FALSE; + +		udelay(hw->eeprom.delay_usec); +	} else if (hw->eeprom.type == e1000_eeprom_microwire) { +		/* cleanup eeprom */ + +		/* CS on Microwire is active-high */ +		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); + +		E1000_WRITE_REG(hw, EECD, eecd); + +		/* Rising edge of clock */ +		eecd |= E1000_EECD_SK; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(hw->eeprom.delay_usec); + +		/* Falling edge of clock */ +		eecd &= ~E1000_EECD_SK; +		E1000_WRITE_REG(hw, EECD, eecd); +		E1000_WRITE_FLUSH(hw); +		udelay(hw->eeprom.delay_usec);  	} -	e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5); -	e1000_shift_out_ee_bits(hw, Reg, (large_eeprom) ? 6 : 4); -	e1000_eeprom_cleanup(hw);  	/* Stop requesting EEPROM access */  	if (hw->mac_type > e1000_82544) { -		eecd = E1000_READ_REG(hw, EECD);  		eecd &= ~E1000_EECD_REQ;  		E1000_WRITE_REG(hw, EECD, eecd);  	} -	i = 0; -	eecd = E1000_READ_REG(hw, EECD); -	while (((eecd & E1000_EECD_GNT)) && (i < 500)) { -		i++; -		udelay(10); -		eecd = E1000_READ_REG(hw, EECD); -	} -	if ((eecd & E1000_EECD_GNT)) { -		DEBUGOUT("Could not release EEPROM grant\n"); +} +/****************************************************************************** + * Reads a 16 bit word from the EEPROM. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +static int32_t +e1000_spi_eeprom_ready(struct e1000_hw *hw) +{ +	uint16_t retry_count = 0; +	uint8_t spi_stat_reg; + +	DEBUGFUNC(); + +	/* 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 +	 * 5 milliseconds, then error out. +	 */ +	retry_count = 0; +	do { +		e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI, +			hw->eeprom.opcode_bits); +		spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8); +		if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI)) +			break; + +		udelay(5); +		retry_count += 5; + +		e1000_standby_eeprom(hw); +	} while (retry_count < EEPROM_MAX_RETRY_SPI); + +	/* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and +	 * only 0-5mSec on 5V devices) +	 */ +	if (retry_count >= EEPROM_MAX_RETRY_SPI) { +		DEBUGOUT("SPI EEPROM Status error\n"); +		return -E1000_ERR_EEPROM;  	} -	return TRUE; + +	return E1000_SUCCESS;  } + +/****************************************************************************** + * Reads a 16 bit word from the EEPROM. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of  word in the EEPROM to read + * data - word read from the EEPROM + *****************************************************************************/ +static int32_t +e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, +		uint16_t words, uint16_t *data) +{ +	struct e1000_eeprom_info *eeprom = &hw->eeprom; +	uint32_t i = 0; + +	DEBUGFUNC(); + +	/* If eeprom is not yet detected, do so now */ +	if (eeprom->word_size == 0) +		e1000_init_eeprom_params(hw); + +	/* A check for invalid values:  offset too large, too many words, +	 * and not enough words. +	 */ +	if ((offset >= eeprom->word_size) || +		(words > eeprom->word_size - offset) || +		(words == 0)) { +		DEBUGOUT("\"words\" parameter out of bounds." +			"Words = %d, size = %d\n", offset, eeprom->word_size); +		return -E1000_ERR_EEPROM; +	} + +	/* EEPROM's that don't use EERD to read require us to bit-bang the SPI +	 * directly. In this case, we need to acquire the EEPROM so that +	 * FW or other port software does not interrupt. +	 */ +	if (e1000_is_onboard_nvm_eeprom(hw) == TRUE && +		hw->eeprom.use_eerd == FALSE) { + +		/* Prepare the EEPROM for bit-bang reading */ +		if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) +			return -E1000_ERR_EEPROM; +	} + +	/* Eerd register EEPROM access requires no eeprom aquire/release */ +	if (eeprom->use_eerd == TRUE) +		return e1000_read_eeprom_eerd(hw, offset, words, data); + +	/* ich8lan does not support currently. if needed, please +	 * add corresponding code and functions. +	 */ +#if 0 +	/* ICH EEPROM access is done via the ICH flash controller */ +	if (eeprom->type == e1000_eeprom_ich8) +		return e1000_read_eeprom_ich8(hw, offset, words, data);  #endif +	/* Set up the SPI or Microwire EEPROM for bit-bang reading.  We have +	 * acquired the EEPROM at this point, so any returns should relase it */ +	if (eeprom->type == e1000_eeprom_spi) { +		uint16_t word_in; +		uint8_t read_opcode = EEPROM_READ_OPCODE_SPI; + +		if (e1000_spi_eeprom_ready(hw)) { +			e1000_release_eeprom(hw); +			return -E1000_ERR_EEPROM; +		} + +		e1000_standby_eeprom(hw); + +		/* Some SPI eeproms use the 8th address bit embedded in +		 * the opcode */ +		if ((eeprom->address_bits == 8) && (offset >= 128)) +			read_opcode |= EEPROM_A8_OPCODE_SPI; + +		/* Send the READ command (opcode + addr)  */ +		e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits); +		e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), +				eeprom->address_bits); + +		/* Read the data.  The address of the eeprom internally +		 * increments with each byte (spi) being read, saving on the +		 * overhead of eeprom setup and tear-down.  The address +		 * counter will roll over if reading beyond the size of +		 * the eeprom, thus allowing the entire memory to be read +		 * starting from any offset. */ +		for (i = 0; i < words; i++) { +			word_in = e1000_shift_in_ee_bits(hw, 16); +			data[i] = (word_in >> 8) | (word_in << 8); +		} +	} else if (eeprom->type == e1000_eeprom_microwire) { +		for (i = 0; i < words; i++) { +			/* Send the READ command (opcode + addr)  */ +			e1000_shift_out_ee_bits(hw, +				EEPROM_READ_OPCODE_MICROWIRE, +				eeprom->opcode_bits); +			e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i), +				eeprom->address_bits); + +			/* Read the data.  For microwire, each word requires +			 * the overhead of eeprom setup and tear-down. */ +			data[i] = e1000_shift_in_ee_bits(hw, 16); +			e1000_standby_eeprom(hw); +		} +	} + +	/* End this read operation */ +	e1000_release_eeprom(hw); + +	return E1000_SUCCESS; +}  /******************************************************************************   * Verifies that the EEPROM has a valid checksum @@ -466,7 +882,7 @@ e1000_validate_eeprom_checksum(struct eth_device *nic)  	DEBUGFUNC();  	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { -		if (e1000_read_eeprom(hw, i, &eeprom_data) < 0) { +		if (e1000_read_eeprom(hw, i, 1,  &eeprom_data) < 0) {  			DEBUGOUT("EEPROM Read Error\n");  			return -E1000_ERR_EEPROM;  		} @@ -482,6 +898,162 @@ e1000_validate_eeprom_checksum(struct eth_device *nic)  }  #endif /* #ifndef CONFIG_AP1000 */ +/*************************************************************************** + * + * Obtaining software semaphore bit (SMBI) before resetting PHY. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to obtain semaphore. + *            E1000_SUCCESS at any other case. + * + ***************************************************************************/ +static int32_t +e1000_get_software_semaphore(struct e1000_hw *hw) +{ +	 int32_t timeout = hw->eeprom.word_size + 1; +	 uint32_t swsm; + +	DEBUGFUNC(); + +	if (hw->mac_type != e1000_80003es2lan) +		return E1000_SUCCESS; + +	while (timeout) { +		swsm = E1000_READ_REG(hw, SWSM); +		/* If SMBI bit cleared, it is now set and we hold +		 * the semaphore */ +		if (!(swsm & E1000_SWSM_SMBI)) +			break; +		mdelay(1); +		timeout--; +	} + +	if (!timeout) { +		DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); +		return -E1000_ERR_RESET; +	} + +	return E1000_SUCCESS; +} + +/*************************************************************************** + * This function clears HW semaphore bits. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - None. + * + ***************************************************************************/ +static void +e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) +{ +	 uint32_t swsm; + +	DEBUGFUNC(); + +	if (!hw->eeprom_semaphore_present) +		return; + +	swsm = E1000_READ_REG(hw, SWSM); +	if (hw->mac_type == e1000_80003es2lan) { +		/* Release both semaphores. */ +		swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); +	} else +		swsm &= ~(E1000_SWSM_SWESMBI); +	E1000_WRITE_REG(hw, SWSM, swsm); +} + +/*************************************************************************** + * + * Using the combination of SMBI and SWESMBI semaphore bits when resetting + * adapter or Eeprom access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_EEPROM if fail to access EEPROM. + *            E1000_SUCCESS at any other case. + * + ***************************************************************************/ +static int32_t +e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) +{ +	int32_t timeout; +	uint32_t swsm; + +	DEBUGFUNC(); + +	if (!hw->eeprom_semaphore_present) +		return E1000_SUCCESS; + +	if (hw->mac_type == e1000_80003es2lan) { +		/* Get the SW semaphore. */ +		if (e1000_get_software_semaphore(hw) != E1000_SUCCESS) +			return -E1000_ERR_EEPROM; +	} + +	/* Get the FW semaphore. */ +	timeout = hw->eeprom.word_size + 1; +	while (timeout) { +		swsm = E1000_READ_REG(hw, SWSM); +		swsm |= E1000_SWSM_SWESMBI; +		E1000_WRITE_REG(hw, SWSM, swsm); +		/* if we managed to set the bit we got the semaphore. */ +		swsm = E1000_READ_REG(hw, SWSM); +		if (swsm & E1000_SWSM_SWESMBI) +			break; + +		udelay(50); +		timeout--; +	} + +	if (!timeout) { +		/* Release semaphores */ +		e1000_put_hw_eeprom_semaphore(hw); +		DEBUGOUT("Driver can't access the Eeprom - " +				"SWESMBI bit is set.\n"); +		return -E1000_ERR_EEPROM; +	} + +	return E1000_SUCCESS; +} + +static int32_t +e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask) +{ +	uint32_t swfw_sync = 0; +	uint32_t swmask = mask; +	uint32_t fwmask = mask << 16; +	int32_t timeout = 200; + +	DEBUGFUNC(); +	while (timeout) { +		if (e1000_get_hw_eeprom_semaphore(hw)) +			return -E1000_ERR_SWFW_SYNC; + +		swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC); +		if (!(swfw_sync & (fwmask | swmask))) +			break; + +		/* firmware currently using resource (fwmask) */ +		/* or other software thread currently using resource (swmask) */ +		e1000_put_hw_eeprom_semaphore(hw); +		mdelay(5); +		timeout--; +	} + +	if (!timeout) { +		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); +		return -E1000_ERR_SWFW_SYNC; +	} + +	swfw_sync |= swmask; +	E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync); + +	e1000_put_hw_eeprom_semaphore(hw); +	return E1000_SUCCESS; +} +  /******************************************************************************   * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the   * second function of dual function devices @@ -501,7 +1073,7 @@ e1000_read_mac_addr(struct eth_device *nic)  	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {  		offset = i >> 1; -		if (e1000_read_eeprom(hw, offset, &eeprom_data) < 0) { +		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {  			DEBUGOUT("EEPROM Read Error\n");  			return -E1000_ERR_EEPROM;  		} @@ -605,7 +1177,7 @@ e1000_clear_vfta(struct e1000_hw *hw)   *   * hw - Struct containing variables accessed by shared code   *****************************************************************************/ -static int +int32_t  e1000_set_mac_type(struct e1000_hw *hw)  {  	DEBUGFUNC(); @@ -636,21 +1208,88 @@ e1000_set_mac_type(struct e1000_hw *hw)  		break;  	case E1000_DEV_ID_82540EM:  	case E1000_DEV_ID_82540EM_LOM: +	case E1000_DEV_ID_82540EP: +	case E1000_DEV_ID_82540EP_LOM: +	case E1000_DEV_ID_82540EP_LP:  		hw->mac_type = e1000_82540;  		break;  	case E1000_DEV_ID_82545EM_COPPER: -	case E1000_DEV_ID_82545GM_COPPER:  	case E1000_DEV_ID_82545EM_FIBER:  		hw->mac_type = e1000_82545;  		break; +	case E1000_DEV_ID_82545GM_COPPER: +	case E1000_DEV_ID_82545GM_FIBER: +	case E1000_DEV_ID_82545GM_SERDES: +		hw->mac_type = e1000_82545_rev_3; +		break;  	case E1000_DEV_ID_82546EB_COPPER:  	case E1000_DEV_ID_82546EB_FIBER: +	case E1000_DEV_ID_82546EB_QUAD_COPPER:  		hw->mac_type = e1000_82546;  		break; +	case E1000_DEV_ID_82546GB_COPPER: +	case E1000_DEV_ID_82546GB_FIBER: +	case E1000_DEV_ID_82546GB_SERDES: +	case E1000_DEV_ID_82546GB_PCIE: +	case E1000_DEV_ID_82546GB_QUAD_COPPER: +	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: +		hw->mac_type = e1000_82546_rev_3; +		break; +	case E1000_DEV_ID_82541EI: +	case E1000_DEV_ID_82541EI_MOBILE: +	case E1000_DEV_ID_82541ER_LOM: +		hw->mac_type = e1000_82541; +		break;  	case E1000_DEV_ID_82541ER: +	case E1000_DEV_ID_82541GI:  	case E1000_DEV_ID_82541GI_LF: +	case E1000_DEV_ID_82541GI_MOBILE:  		hw->mac_type = e1000_82541_rev_2;  		break; +	case E1000_DEV_ID_82547EI: +	case E1000_DEV_ID_82547EI_MOBILE: +		hw->mac_type = e1000_82547; +		break; +	case E1000_DEV_ID_82547GI: +		hw->mac_type = e1000_82547_rev_2; +		break; +	case E1000_DEV_ID_82571EB_COPPER: +	case E1000_DEV_ID_82571EB_FIBER: +	case E1000_DEV_ID_82571EB_SERDES: +	case E1000_DEV_ID_82571EB_SERDES_DUAL: +	case E1000_DEV_ID_82571EB_SERDES_QUAD: +	case E1000_DEV_ID_82571EB_QUAD_COPPER: +	case E1000_DEV_ID_82571PT_QUAD_COPPER: +	case E1000_DEV_ID_82571EB_QUAD_FIBER: +	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: +		hw->mac_type = e1000_82571; +		break; +	case E1000_DEV_ID_82572EI_COPPER: +	case E1000_DEV_ID_82572EI_FIBER: +	case E1000_DEV_ID_82572EI_SERDES: +	case E1000_DEV_ID_82572EI: +		hw->mac_type = e1000_82572; +		break; +	case E1000_DEV_ID_82573E: +	case E1000_DEV_ID_82573E_IAMT: +	case E1000_DEV_ID_82573L: +		hw->mac_type = e1000_82573; +		break; +	case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: +	case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: +	case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: +	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: +		hw->mac_type = e1000_80003es2lan; +		break; +	case E1000_DEV_ID_ICH8_IGP_M_AMT: +	case E1000_DEV_ID_ICH8_IGP_AMT: +	case E1000_DEV_ID_ICH8_IGP_C: +	case E1000_DEV_ID_ICH8_IFE: +	case E1000_DEV_ID_ICH8_IFE_GT: +	case E1000_DEV_ID_ICH8_IFE_G: +	case E1000_DEV_ID_ICH8_IGP_M: +		hw->mac_type = e1000_ich8lan; +		break;  	default:  		/* Should never have loaded on this device */  		return -E1000_ERR_MAC_TYPE; @@ -677,8 +1316,7 @@ e1000_reset_hw(struct e1000_hw *hw)  	if (hw->mac_type == e1000_82542_rev2_0) {  		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");  		pci_write_config_word(hw->pdev, PCI_COMMAND, -				      hw-> -				      pci_cmd_word & ~PCI_COMMAND_INVALIDATE); +				hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE);  	}  	/* Clear interrupt mask to stop board from generating interrupts */ @@ -709,12 +1347,7 @@ e1000_reset_hw(struct e1000_hw *hw)  	DEBUGOUT("Issuing a global reset to MAC\n");  	ctrl = E1000_READ_REG(hw, CTRL); -#if 0 -	if (hw->mac_type > e1000_82543) -		E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); -	else -#endif -		E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); +	E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));  	/* Force a reload from the EEPROM if necessary */  	if (hw->mac_type < e1000_82540) { @@ -746,6 +1379,127 @@ e1000_reset_hw(struct e1000_hw *hw)  	if (hw->mac_type == e1000_82542_rev2_0) {  		pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);  	} +	E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA); +} + +/****************************************************************************** + * + * Initialize a number of hardware-dependent bits + * + * hw: Struct containing variables accessed by shared code + * + * This function contains hardware limitation workarounds for PCI-E adapters + * + *****************************************************************************/ +static void +e1000_initialize_hardware_bits(struct e1000_hw *hw) +{ +	if ((hw->mac_type >= e1000_82571) && +			(!hw->initialize_hw_bits_disable)) { +		/* Settings common to all PCI-express silicon */ +		uint32_t reg_ctrl, reg_ctrl_ext; +		uint32_t reg_tarc0, reg_tarc1; +		uint32_t reg_tctl; +		uint32_t reg_txdctl, reg_txdctl1; + +		/* link autonegotiation/sync workarounds */ +		reg_tarc0 = E1000_READ_REG(hw, TARC0); +		reg_tarc0 &= ~((1 << 30)|(1 << 29)|(1 << 28)|(1 << 27)); + +		/* Enable not-done TX descriptor counting */ +		reg_txdctl = E1000_READ_REG(hw, TXDCTL); +		reg_txdctl |= E1000_TXDCTL_COUNT_DESC; +		E1000_WRITE_REG(hw, TXDCTL, reg_txdctl); + +		reg_txdctl1 = E1000_READ_REG(hw, TXDCTL1); +		reg_txdctl1 |= E1000_TXDCTL_COUNT_DESC; +		E1000_WRITE_REG(hw, TXDCTL1, reg_txdctl1); + +		switch (hw->mac_type) { +		case e1000_82571: +		case e1000_82572: +			/* Clear PHY TX compatible mode bits */ +			reg_tarc1 = E1000_READ_REG(hw, TARC1); +			reg_tarc1 &= ~((1 << 30)|(1 << 29)); + +			/* link autonegotiation/sync workarounds */ +			reg_tarc0 |= ((1 << 26)|(1 << 25)|(1 << 24)|(1 << 23)); + +			/* TX ring control fixes */ +			reg_tarc1 |= ((1 << 26)|(1 << 25)|(1 << 24)); + +			/* Multiple read bit is reversed polarity */ +			reg_tctl = E1000_READ_REG(hw, TCTL); +			if (reg_tctl & E1000_TCTL_MULR) +				reg_tarc1 &= ~(1 << 28); +			else +				reg_tarc1 |= (1 << 28); + +			E1000_WRITE_REG(hw, TARC1, reg_tarc1); +			break; +		case e1000_82573: +			reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); +			reg_ctrl_ext &= ~(1 << 23); +			reg_ctrl_ext |= (1 << 22); + +			/* TX byte count fix */ +			reg_ctrl = E1000_READ_REG(hw, CTRL); +			reg_ctrl &= ~(1 << 29); + +			E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); +			E1000_WRITE_REG(hw, CTRL, reg_ctrl); +			break; +		case e1000_80003es2lan: +	/* improve small packet performace for fiber/serdes */ +			if ((hw->media_type == e1000_media_type_fiber) +			|| (hw->media_type == +				e1000_media_type_internal_serdes)) { +				reg_tarc0 &= ~(1 << 20); +			} + +		/* Multiple read bit is reversed polarity */ +			reg_tctl = E1000_READ_REG(hw, TCTL); +			reg_tarc1 = E1000_READ_REG(hw, TARC1); +			if (reg_tctl & E1000_TCTL_MULR) +				reg_tarc1 &= ~(1 << 28); +			else +				reg_tarc1 |= (1 << 28); + +			E1000_WRITE_REG(hw, TARC1, reg_tarc1); +			break; +		case e1000_ich8lan: +			/* Reduce concurrent DMA requests to 3 from 4 */ +			if ((hw->revision_id < 3) || +			((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && +				(hw->device_id != E1000_DEV_ID_ICH8_IGP_M))) +				reg_tarc0 |= ((1 << 29)|(1 << 28)); + +			reg_ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); +			reg_ctrl_ext |= (1 << 22); +			E1000_WRITE_REG(hw, CTRL_EXT, reg_ctrl_ext); + +			/* workaround TX hang with TSO=on */ +			reg_tarc0 |= ((1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)); + +			/* Multiple read bit is reversed polarity */ +			reg_tctl = E1000_READ_REG(hw, TCTL); +			reg_tarc1 = E1000_READ_REG(hw, TARC1); +			if (reg_tctl & E1000_TCTL_MULR) +				reg_tarc1 &= ~(1 << 28); +			else +				reg_tarc1 |= (1 << 28); + +			/* workaround TX hang with TSO=on */ +			reg_tarc1 |= ((1 << 30)|(1 << 26)|(1 << 24)); + +			E1000_WRITE_REG(hw, TARC1, reg_tarc1); +			break; +		default: +			break; +		} + +		E1000_WRITE_REG(hw, TARC0, reg_tarc0); +	}  }  /****************************************************************************** @@ -763,49 +1517,43 @@ static int  e1000_init_hw(struct eth_device *nic)  {  	struct e1000_hw *hw = nic->priv; -	uint32_t ctrl, status; +	uint32_t ctrl;  	uint32_t i;  	int32_t ret_val;  	uint16_t pcix_cmd_word;  	uint16_t pcix_stat_hi_word;  	uint16_t cmd_mmrbc;  	uint16_t stat_mmrbc; -	e1000_bus_type bus_type = e1000_bus_type_unknown; - +	uint32_t mta_size; +	uint32_t reg_data; +	uint32_t ctrl_ext;  	DEBUGFUNC(); -#if 0 -	/* Initialize Identification LED */ -	ret_val = e1000_id_led_init(hw); -	if (ret_val < 0) { -		DEBUGOUT("Error Initializing Identification LED\n"); -		return ret_val; -	} -#endif -	/* Set the Media Type and exit with error if it is not valid. */ -	if (hw->mac_type != e1000_82543) { -		/* tbi_compatibility is only valid on 82543 */ -		hw->tbi_compatibility_en = FALSE; +	/* force full DMA clock frequency for 10/100 on ICH8 A0-B0 */ +	if ((hw->mac_type == e1000_ich8lan) && +		((hw->revision_id < 3) || +		((hw->device_id != E1000_DEV_ID_ICH8_IGP_M_AMT) && +		(hw->device_id != E1000_DEV_ID_ICH8_IGP_M)))) { +			reg_data = E1000_READ_REG(hw, STATUS); +			reg_data &= ~0x80000000; +			E1000_WRITE_REG(hw, STATUS, reg_data);  	} +	/* Do not need initialize Identification LED */ -	if (hw->mac_type >= e1000_82543) { -		status = E1000_READ_REG(hw, STATUS); -		if (status & E1000_STATUS_TBIMODE) { -			hw->media_type = e1000_media_type_fiber; -			/* tbi_compatibility not valid on fiber */ -			hw->tbi_compatibility_en = FALSE; -		} else { -			hw->media_type = e1000_media_type_copper; -		} -	} else { -		/* This is an 82542 (fiber only) */ -		hw->media_type = e1000_media_type_fiber; -	} +	/* Set the media type and TBI compatibility */ +	e1000_set_media_type(hw); + +	/* Must be called after e1000_set_media_type +	 * because media_type is used */ +	e1000_initialize_hardware_bits(hw);  	/* Disabling VLAN filtering. */  	DEBUGOUT("Initializing the IEEE VLAN\n"); -	E1000_WRITE_REG(hw, VET, 0); - -	e1000_clear_vfta(hw); +	/* VET hardcoded to standard value and VFTA removed in ICH8 LAN */ +	if (hw->mac_type != e1000_ich8lan) { +		if (hw->mac_type < e1000_82545_rev_3) +			E1000_WRITE_REG(hw, VET, 0); +		e1000_clear_vfta(hw); +	}  	/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */  	if (hw->mac_type == e1000_82542_rev2_0) { @@ -833,26 +1581,33 @@ e1000_init_hw(struct eth_device *nic)  	/* Zero out the Multicast HASH table */  	DEBUGOUT("Zeroing the MTA\n"); -	for (i = 0; i < E1000_MC_TBL_SIZE; i++) +	mta_size = E1000_MC_TBL_SIZE; +	if (hw->mac_type == e1000_ich8lan) +		mta_size = E1000_MC_TBL_SIZE_ICH8LAN; +	for (i = 0; i < mta_size; i++) {  		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); - +		/* use write flush to prevent Memory Write Block (MWB) from +		 * occuring when accessing our register space */ +		E1000_WRITE_FLUSH(hw); +	}  #if 0  	/* Set the PCI priority bit correctly in the CTRL register.  This  	 * determines if the adapter gives priority to receives, or if it -	 * gives equal priority to transmits and receives. +	 * gives equal priority to transmits and receives.  Valid only on +	 * 82542 and 82543 silicon.  	 */ -	if (hw->dma_fairness) { +	if (hw->dma_fairness && hw->mac_type <= e1000_82543) {  		ctrl = E1000_READ_REG(hw, CTRL);  		E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);  	}  #endif -	if (hw->mac_type >= e1000_82543) { -		status = E1000_READ_REG(hw, STATUS); -		bus_type = (status & E1000_STATUS_PCIX_MODE) ? -		    e1000_bus_type_pcix : e1000_bus_type_pci; -	} +	switch (hw->mac_type) { +	case e1000_82545_rev_3: +	case e1000_82546_rev_3: +		break; +	default:  	/* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */ -	if (bus_type == e1000_bus_type_pcix) { +	if (hw->bus_type == e1000_bus_type_pcix) {  		pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER,  				     &pcix_cmd_word);  		pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, @@ -872,6 +1627,12 @@ e1000_init_hw(struct eth_device *nic)  					      pcix_cmd_word);  		}  	} +		break; +	} + +	/* More time needed for PHY to initialize */ +	if (hw->mac_type == e1000_ich8lan) +		mdelay(15);  	/* Call a subroutine to configure the link and setup flow control. */  	ret_val = e1000_setup_link(nic); @@ -884,6 +1645,48 @@ e1000_init_hw(struct eth_device *nic)  		    E1000_TXDCTL_FULL_TX_DESC_WB;  		E1000_WRITE_REG(hw, TXDCTL, ctrl);  	} + +	switch (hw->mac_type) { +	default: +		break; +	case e1000_80003es2lan: +		/* Enable retransmit on late collisions */ +		reg_data = E1000_READ_REG(hw, TCTL); +		reg_data |= E1000_TCTL_RTLC; +		E1000_WRITE_REG(hw, TCTL, reg_data); + +		/* Configure Gigabit Carry Extend Padding */ +		reg_data = E1000_READ_REG(hw, TCTL_EXT); +		reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; +		reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX; +		E1000_WRITE_REG(hw, TCTL_EXT, reg_data); + +		/* Configure Transmit Inter-Packet Gap */ +		reg_data = E1000_READ_REG(hw, TIPG); +		reg_data &= ~E1000_TIPG_IPGT_MASK; +		reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; +		E1000_WRITE_REG(hw, TIPG, reg_data); + +		reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001); +		reg_data &= ~0x00100000; +		E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data); +		/* Fall through */ +	case e1000_82571: +	case e1000_82572: +	case e1000_ich8lan: +		ctrl = E1000_READ_REG(hw, TXDCTL1); +		ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) +			| E1000_TXDCTL_FULL_TX_DESC_WB; +		E1000_WRITE_REG(hw, TXDCTL1, ctrl); +		break; +	} + +	if (hw->mac_type == e1000_82573) { +		uint32_t gcr = E1000_READ_REG(hw, GCR); +		gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; +		E1000_WRITE_REG(hw, GCR, gcr); +	} +  #if 0  	/* Clear all of the statistics registers (clear on read).  It is  	 * important that we do this after we have tried to establish link @@ -891,8 +1694,22 @@ e1000_init_hw(struct eth_device *nic)  	 * is no link.  	 */  	e1000_clear_hw_cntrs(hw); + +	/* ICH8 No-snoop bits are opposite polarity. +	 * Set to snoop by default after reset. */ +	if (hw->mac_type == e1000_ich8lan) +		e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);  #endif +	if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || +		hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) { +		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); +		/* Relaxed ordering must be disabled to avoid a parity +		 * error crash in a PCI slot. */ +		ctrl_ext |= E1000_CTRL_EXT_RO_DIS; +		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); +	} +  	return ret_val;  } @@ -917,6 +1734,11 @@ e1000_setup_link(struct eth_device *nic)  	DEBUGFUNC(); +	/* In the case of the phy reset being blocked, we already have a link. +	 * We do not have to set it up again. */ +	if (e1000_check_phy_reset_block(hw)) +		return E1000_SUCCESS; +  #ifndef CONFIG_AP1000  	/* Read and store word 0x0F of the EEPROM. This word contains bits  	 * that determine the hardware's default PAUSE (flow control) mode, @@ -926,7 +1748,8 @@ e1000_setup_link(struct eth_device *nic)  	 * control setting, then the variable hw->fc will  	 * be initialized based on a value in the EEPROM.  	 */ -	if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, &eeprom_data) < 0) { +	if (e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, +				&eeprom_data) < 0) {  		DEBUGOUT("EEPROM Read Error\n");  		return -E1000_ERR_EEPROM;  	} @@ -937,13 +1760,31 @@ e1000_setup_link(struct eth_device *nic)  #endif  	if (hw->fc == e1000_fc_default) { -		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) -			hw->fc = e1000_fc_none; -		else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == -			 EEPROM_WORD0F_ASM_DIR) -			hw->fc = e1000_fc_tx_pause; -		else +		switch (hw->mac_type) { +		case e1000_ich8lan: +		case e1000_82573:  			hw->fc = e1000_fc_full; +			break; +		default: +#ifndef CONFIG_AP1000 +			ret_val = e1000_read_eeprom(hw, +				EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data); +			if (ret_val) { +				DEBUGOUT("EEPROM Read Error\n"); +				return -E1000_ERR_EEPROM; +			} +#else +			eeprom_data = 0xb220; +#endif +			if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0) +				hw->fc = e1000_fc_none; +			else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == +				    EEPROM_WORD0F_ASM_DIR) +				hw->fc = e1000_fc_tx_pause; +			else +				hw->fc = e1000_fc_full; +			break; +		}  	}  	/* We want to save off the original Flow Control configuration just @@ -985,12 +1826,16 @@ e1000_setup_link(struct eth_device *nic)  	 * control is disabled, because it does not hurt anything to  	 * initialize these registers.  	 */ -	DEBUGOUT -	    ("Initializing the Flow Control address, type and timer regs\n"); +	DEBUGOUT("Initializing the Flow Control address, type" +			"and timer regs\n"); + +	/* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */ +	if (hw->mac_type != e1000_ich8lan) { +		E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); +		E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); +		E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); +	} -	E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); -	E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); -	E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);  	E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);  	/* Set the flow control receive threshold registers.  Normally, @@ -1154,18 +1999,57 @@ e1000_setup_fiber_link(struct eth_device *nic)  	return 0;  } +/***************************************************************************** + * Set PHY to class A mode + * Assumes the following operations will follow to enable the new class mode. + *  1. Do a PHY soft reset + *  2. Restart auto-negotiation or force link. + * + * hw - Struct containing variables accessed by shared code + ****************************************************************************/ +static int32_t +e1000_set_phy_mode(struct e1000_hw *hw) +{ +	int32_t ret_val; +	uint16_t eeprom_data; + +	DEBUGFUNC(); + +	if ((hw->mac_type == e1000_82545_rev_3) && +		(hw->media_type == e1000_media_type_copper)) { +		ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, +				1, &eeprom_data); +		if (ret_val) +			return ret_val; + +		if ((eeprom_data != EEPROM_RESERVED_WORD) && +			(eeprom_data & EEPROM_PHY_CLASS_A)) { +			ret_val = e1000_write_phy_reg(hw, +					M88E1000_PHY_PAGE_SELECT, 0x000B); +			if (ret_val) +				return ret_val; +			ret_val = e1000_write_phy_reg(hw, +					M88E1000_PHY_GEN_CONTROL, 0x8104); +			if (ret_val) +				return ret_val; + +			hw->phy_reset_disable = FALSE; +		} +	} + +	return E1000_SUCCESS; +} +  /****************************************************************************** -* Detects which PHY is present and the speed and duplex +* Make sure we have a valid PHY and change PHY mode before link setup.  *  * hw - Struct containing variables accessed by shared code  ******************************************************************************/ -static int -e1000_setup_copper_link(struct eth_device *nic) +static int32_t +e1000_copper_link_preconfig(struct e1000_hw *hw)  { -	struct e1000_hw *hw = nic->priv;  	uint32_t ctrl;  	int32_t ret_val; -	uint16_t i;  	uint16_t phy_data;  	DEBUGFUNC(); @@ -1180,28 +2064,684 @@ e1000_setup_copper_link(struct eth_device *nic)  		ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);  		E1000_WRITE_REG(hw, CTRL, ctrl);  	} else { -		ctrl |= -		    (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); +		ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX +				| E1000_CTRL_SLU);  		E1000_WRITE_REG(hw, CTRL, ctrl); -		e1000_phy_hw_reset(hw); +		ret_val = e1000_phy_hw_reset(hw); +		if (ret_val) +			return ret_val;  	}  	/* Make sure we have a valid PHY */  	ret_val = e1000_detect_gig_phy(hw); -	if (ret_val < 0) { +	if (ret_val) {  		DEBUGOUT("Error, did not detect valid phy.\n");  		return ret_val;  	}  	DEBUGOUT("Phy ID = %x \n", hw->phy_id); -	/* Enable CRS on TX. This must be set for half-duplex operation. */ -	if (e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; +#ifndef CONFIG_AP1000 +	/* Set PHY to class A mode (if necessary) */ +	ret_val = e1000_set_phy_mode(hw); +	if (ret_val) +		return ret_val; +#endif +	if ((hw->mac_type == e1000_82545_rev_3) || +		(hw->mac_type == e1000_82546_rev_3)) { +		ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, +				&phy_data); +		phy_data |= 0x00000008; +		ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, +				phy_data); +	} + +	if (hw->mac_type <= e1000_82543 || +		hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 || +		hw->mac_type == e1000_82541_rev_2 +		|| hw->mac_type == e1000_82547_rev_2) +			hw->phy_reset_disable = FALSE; + +	return E1000_SUCCESS; +} + +/***************************************************************************** + * + * This function sets the lplu state according to the active flag.  When + * activating lplu this function also disables smart speed and vise versa. + * lplu will not be activated unless the device autonegotiation advertisment + * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. + * hw: Struct containing variables accessed by shared code + * active - true to enable lplu false to disable lplu. + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + *            E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +static int32_t +e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active) +{ +	uint32_t phy_ctrl = 0; +	int32_t ret_val; +	uint16_t phy_data; +	DEBUGFUNC(); + +	if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2 +	    && hw->phy_type != e1000_phy_igp_3) +		return E1000_SUCCESS; + +	/* During driver activity LPLU should not be used or it will attain link +	 * from the lowest speeds starting from 10Mbps. The capability is used +	 * for Dx transitions and states */ +	if (hw->mac_type == e1000_82541_rev_2 +			|| hw->mac_type == e1000_82547_rev_2) { +		ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, +				&phy_data); +		if (ret_val) +			return ret_val; +	} else if (hw->mac_type == e1000_ich8lan) { +		/* MAC writes into PHY register based on the state transition +		 * and start auto-negotiation. SW driver can overwrite the +		 * settings in CSR PHY power control E1000_PHY_CTRL register. */ +		phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); +	} else { +		ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, +				&phy_data); +		if (ret_val) +			return ret_val; +	} + +	if (!active) { +		if (hw->mac_type == e1000_82541_rev_2 || +			hw->mac_type == e1000_82547_rev_2) { +			phy_data &= ~IGP01E1000_GMII_FLEX_SPD; +			ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, +					phy_data); +			if (ret_val) +				return ret_val; +		} else { +			if (hw->mac_type == e1000_ich8lan) { +				phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; +				E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); +			} else { +				phy_data &= ~IGP02E1000_PM_D3_LPLU; +				ret_val = e1000_write_phy_reg(hw, +					IGP02E1000_PHY_POWER_MGMT, phy_data); +				if (ret_val) +					return ret_val; +			} +		} + +	/* 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 (hw->smart_speed == e1000_smart_speed_on) { +			ret_val = e1000_read_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, &phy_data); +			if (ret_val) +				return ret_val; + +			phy_data |= IGP01E1000_PSCFR_SMART_SPEED; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, phy_data); +			if (ret_val) +				return ret_val; +		} else if (hw->smart_speed == e1000_smart_speed_off) { +			ret_val = e1000_read_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, &phy_data); +			if (ret_val) +				return ret_val; + +			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, phy_data); +			if (ret_val) +				return ret_val; +		} + +	} else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) +		|| (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL) || +		(hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { + +		if (hw->mac_type == e1000_82541_rev_2 || +		    hw->mac_type == e1000_82547_rev_2) { +			phy_data |= IGP01E1000_GMII_FLEX_SPD; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_GMII_FIFO, phy_data); +			if (ret_val) +				return ret_val; +		} else { +			if (hw->mac_type == e1000_ich8lan) { +				phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; +				E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); +			} else { +				phy_data |= IGP02E1000_PM_D3_LPLU; +				ret_val = e1000_write_phy_reg(hw, +					IGP02E1000_PHY_POWER_MGMT, phy_data); +				if (ret_val) +					return ret_val; +			} +		} + +		/* When LPLU is enabled we should disable SmartSpeed */ +		ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, +				&phy_data); +		if (ret_val) +			return ret_val; + +		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; +		ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, +				phy_data); +		if (ret_val) +			return ret_val; +	} +	return E1000_SUCCESS; +} + +/***************************************************************************** + * + * This function sets the lplu d0 state according to the active flag.  When + * activating lplu this function also disables smart speed and vise versa. + * lplu will not be activated unless the device autonegotiation advertisment + * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. + * hw: Struct containing variables accessed by shared code + * active - true to enable lplu false to disable lplu. + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + *            E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +static int32_t +e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active) +{ +	uint32_t phy_ctrl = 0; +	int32_t ret_val; +	uint16_t phy_data; +	DEBUGFUNC(); + +	if (hw->mac_type <= e1000_82547_rev_2) +		return E1000_SUCCESS; + +	if (hw->mac_type == e1000_ich8lan) { +		phy_ctrl = E1000_READ_REG(hw, PHY_CTRL); +	} else { +		ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, +				&phy_data); +		if (ret_val) +			return ret_val; +	} + +	if (!active) { +		if (hw->mac_type == e1000_ich8lan) { +			phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; +			E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); +		} else { +			phy_data &= ~IGP02E1000_PM_D0_LPLU; +			ret_val = e1000_write_phy_reg(hw, +					IGP02E1000_PHY_POWER_MGMT, phy_data); +			if (ret_val) +				return ret_val; +		} + +	/* 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 (hw->smart_speed == e1000_smart_speed_on) { +			ret_val = e1000_read_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, &phy_data); +			if (ret_val) +				return ret_val; + +			phy_data |= IGP01E1000_PSCFR_SMART_SPEED; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, phy_data); +			if (ret_val) +				return ret_val; +		} else if (hw->smart_speed == e1000_smart_speed_off) { +			ret_val = e1000_read_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, &phy_data); +			if (ret_val) +				return ret_val; + +			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, phy_data); +			if (ret_val) +				return ret_val; +		} + + +	} else { + +		if (hw->mac_type == e1000_ich8lan) { +			phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; +			E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl); +		} else { +			phy_data |= IGP02E1000_PM_D0_LPLU; +			ret_val = e1000_write_phy_reg(hw, +					IGP02E1000_PHY_POWER_MGMT, phy_data); +			if (ret_val) +				return ret_val; +		} + +		/* When LPLU is enabled we should disable SmartSpeed */ +		ret_val = e1000_read_phy_reg(hw, +				IGP01E1000_PHY_PORT_CONFIG, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; +		ret_val = e1000_write_phy_reg(hw, +				IGP01E1000_PHY_PORT_CONFIG, phy_data); +		if (ret_val) +			return ret_val; + +	} +	return E1000_SUCCESS; +} + +/******************************************************************** +* Copper link setup for e1000_phy_igp series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_igp_setup(struct e1000_hw *hw) +{ +	uint32_t led_ctrl; +	int32_t ret_val; +	uint16_t phy_data; + +	DEBUGOUT(); + +	if (hw->phy_reset_disable) +		return E1000_SUCCESS; + +	ret_val = e1000_phy_reset(hw); +	if (ret_val) { +		DEBUGOUT("Error Resetting the PHY\n"); +		return ret_val; +	} + +	/* Wait 15ms for MAC to configure PHY from eeprom settings */ +	mdelay(15); +	if (hw->mac_type != e1000_ich8lan) { +		/* Configure activity LED after PHY reset */ +		led_ctrl = E1000_READ_REG(hw, LEDCTL); +		led_ctrl &= IGP_ACTIVITY_LED_MASK; +		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); +		E1000_WRITE_REG(hw, LEDCTL, led_ctrl);  	} + +	/* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */ +	if (hw->phy_type == e1000_phy_igp) { +		/* disable lplu d3 during driver init */ +		ret_val = e1000_set_d3_lplu_state(hw, FALSE); +		if (ret_val) { +			DEBUGOUT("Error Disabling LPLU D3\n"); +			return ret_val; +		} +	} + +	/* disable lplu d0 during driver init */ +	ret_val = e1000_set_d0_lplu_state(hw, FALSE); +	if (ret_val) { +		DEBUGOUT("Error Disabling LPLU D0\n"); +		return ret_val; +	} +	/* Configure mdi-mdix settings */ +	ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); +	if (ret_val) +		return ret_val; + +	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { +		hw->dsp_config_state = e1000_dsp_config_disabled; +		/* Force MDI for earlier revs of the IGP PHY */ +		phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX +				| IGP01E1000_PSCR_FORCE_MDI_MDIX); +		hw->mdix = 1; + +	} else { +		hw->dsp_config_state = e1000_dsp_config_enabled; +		phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; + +		switch (hw->mdix) { +		case 1: +			phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; +			break; +		case 2: +			phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; +			break; +		case 0: +		default: +			phy_data |= IGP01E1000_PSCR_AUTO_MDIX; +			break; +		} +	} +	ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); +	if (ret_val) +		return ret_val; + +	/* set auto-master slave resolution settings */ +	if (hw->autoneg) { +		e1000_ms_type phy_ms_setting = hw->master_slave; + +		if (hw->ffe_config_state == e1000_ffe_config_active) +			hw->ffe_config_state = e1000_ffe_config_enabled; + +		if (hw->dsp_config_state == e1000_dsp_config_activated) +			hw->dsp_config_state = e1000_dsp_config_enabled; + +		/* when autonegotiation advertisment is only 1000Mbps then we +		  * should disable SmartSpeed and enable Auto MasterSlave +		  * resolution as hardware default. */ +		if (hw->autoneg_advertised == ADVERTISE_1000_FULL) { +			/* Disable SmartSpeed */ +			ret_val = e1000_read_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, &phy_data); +			if (ret_val) +				return ret_val; +			phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; +			ret_val = e1000_write_phy_reg(hw, +					IGP01E1000_PHY_PORT_CONFIG, phy_data); +			if (ret_val) +				return ret_val; +			/* Set auto Master/Slave resolution process */ +			ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, +					&phy_data); +			if (ret_val) +				return ret_val; +			phy_data &= ~CR_1000T_MS_ENABLE; +			ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, +					phy_data); +			if (ret_val) +				return ret_val; +		} + +		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +		/* load defaults for future use */ +		hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? +				((phy_data & CR_1000T_MS_VALUE) ? +				e1000_ms_force_master : +				e1000_ms_force_slave) : +				e1000_ms_auto; + +		switch (phy_ms_setting) { +		case e1000_ms_force_master: +			phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); +			break; +		case e1000_ms_force_slave: +			phy_data |= CR_1000T_MS_ENABLE; +			phy_data &= ~(CR_1000T_MS_VALUE); +			break; +		case e1000_ms_auto: +			phy_data &= ~CR_1000T_MS_ENABLE; +		default: +			break; +		} +		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); +		if (ret_val) +			return ret_val; +	} + +	return E1000_SUCCESS; +} + +/***************************************************************************** + * This function checks the mode of the firmware. + * + * returns  - TRUE when the mode is IAMT or FALSE. + ****************************************************************************/ +boolean_t +e1000_check_mng_mode(struct e1000_hw *hw) +{ +	uint32_t fwsm; +	DEBUGFUNC(); + +	fwsm = E1000_READ_REG(hw, FWSM); + +	if (hw->mac_type == e1000_ich8lan) { +		if ((fwsm & E1000_FWSM_MODE_MASK) == +		    (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) +			return TRUE; +	} else if ((fwsm & E1000_FWSM_MODE_MASK) == +		       (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) +			return TRUE; + +	return FALSE; +} + +static int32_t +e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data) +{ +	uint32_t reg_val; +	uint16_t swfw; +	DEBUGFUNC(); + +	if ((hw->mac_type == e1000_80003es2lan) && +		(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { +		swfw = E1000_SWFW_PHY1_SM; +	} else { +		swfw = E1000_SWFW_PHY0_SM; +	} +	if (e1000_swfw_sync_acquire(hw, swfw)) +		return -E1000_ERR_SWFW_SYNC; + +	reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) +			& E1000_KUMCTRLSTA_OFFSET) | data; +	E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); +	udelay(2); + +	return E1000_SUCCESS; +} + +static int32_t +e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data) +{ +	uint32_t reg_val; +	uint16_t swfw; +	DEBUGFUNC(); + +	if ((hw->mac_type == e1000_80003es2lan) && +	    (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { +		swfw = E1000_SWFW_PHY1_SM; +	} else { +		swfw = E1000_SWFW_PHY0_SM; +	} +	if (e1000_swfw_sync_acquire(hw, swfw)) +		return -E1000_ERR_SWFW_SYNC; + +	/* Write register address */ +	reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) & +			E1000_KUMCTRLSTA_OFFSET) | E1000_KUMCTRLSTA_REN; +	E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val); +	udelay(2); + +	/* Read the data returned */ +	reg_val = E1000_READ_REG(hw, KUMCTRLSTA); +	*data = (uint16_t)reg_val; + +	return E1000_SUCCESS; +} + +/******************************************************************** +* Copper link setup for e1000_phy_gg82563 series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_ggp_setup(struct e1000_hw *hw) +{ +	int32_t ret_val; +	uint16_t phy_data; +	uint32_t reg_data; + +	DEBUGFUNC(); + +	if (!hw->phy_reset_disable) { +		/* Enable CRS on TX for half-duplex operation. */ +		ret_val = e1000_read_phy_reg(hw, +				GG82563_PHY_MAC_SPEC_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; +		/* Use 25MHz for both link down and 1000BASE-T for Tx clock */ +		phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ; + +		ret_val = e1000_write_phy_reg(hw, +				GG82563_PHY_MAC_SPEC_CTRL, phy_data); +		if (ret_val) +			return ret_val; + +		/* Options: +		 *   MDI/MDI-X = 0 (default) +		 *   0 - Auto for all speeds +		 *   1 - MDI mode +		 *   2 - MDI-X mode +		 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) +		 */ +		ret_val = e1000_read_phy_reg(hw, +				GG82563_PHY_SPEC_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; + +		switch (hw->mdix) { +		case 1: +			phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI; +			break; +		case 2: +			phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; +			break; +		case 0: +		default: +			phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; +			break; +		} + +		/* Options: +		 *   disable_polarity_correction = 0 (default) +		 *       Automatic Correction for Reversed Cable Polarity +		 *   0 - Disabled +		 *   1 - Enabled +		 */ +		phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; +		ret_val = e1000_write_phy_reg(hw, +				GG82563_PHY_SPEC_CTRL, phy_data); + +		if (ret_val) +			return ret_val; + +		/* SW Reset the PHY so all changes take effect */ +		ret_val = e1000_phy_reset(hw); +		if (ret_val) { +			DEBUGOUT("Error Resetting the PHY\n"); +			return ret_val; +		} +	} /* phy_reset_disable */ + +	if (hw->mac_type == e1000_80003es2lan) { +		/* Bypass RX and TX FIFO's */ +		ret_val = e1000_write_kmrn_reg(hw, +				E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL, +				E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS +				| E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS); +		if (ret_val) +			return ret_val; + +		ret_val = e1000_read_phy_reg(hw, +				GG82563_PHY_SPEC_CTRL_2, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; +		ret_val = e1000_write_phy_reg(hw, +				GG82563_PHY_SPEC_CTRL_2, phy_data); + +		if (ret_val) +			return ret_val; + +		reg_data = E1000_READ_REG(hw, CTRL_EXT); +		reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); +		E1000_WRITE_REG(hw, CTRL_EXT, reg_data); + +		ret_val = e1000_read_phy_reg(hw, +				GG82563_PHY_PWR_MGMT_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +	/* Do not init these registers when the HW is in IAMT mode, since the +	 * firmware will have already initialized them.  We only initialize +	 * them if the HW is not in IAMT mode. +	 */ +		if (e1000_check_mng_mode(hw) == FALSE) { +			/* Enable Electrical Idle on the PHY */ +			phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; +			ret_val = e1000_write_phy_reg(hw, +					GG82563_PHY_PWR_MGMT_CTRL, phy_data); +			if (ret_val) +				return ret_val; + +			ret_val = e1000_read_phy_reg(hw, +					GG82563_PHY_KMRN_MODE_CTRL, &phy_data); +			if (ret_val) +				return ret_val; + +			phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; +			ret_val = e1000_write_phy_reg(hw, +					GG82563_PHY_KMRN_MODE_CTRL, phy_data); + +			if (ret_val) +				return ret_val; +		} + +		/* Workaround: Disable padding in Kumeran interface in the MAC +		 * and in the PHY to avoid CRC errors. +		 */ +		ret_val = e1000_read_phy_reg(hw, +				GG82563_PHY_INBAND_CTRL, &phy_data); +		if (ret_val) +			return ret_val; +		phy_data |= GG82563_ICR_DIS_PADDING; +		ret_val = e1000_write_phy_reg(hw, +				GG82563_PHY_INBAND_CTRL, phy_data); +		if (ret_val) +			return ret_val; +	} +	return E1000_SUCCESS; +} + +/******************************************************************** +* Copper link setup for e1000_phy_m88 series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_mgp_setup(struct e1000_hw *hw) +{ +	int32_t ret_val; +	uint16_t phy_data; + +	DEBUGFUNC(); + +	if (hw->phy_reset_disable) +		return E1000_SUCCESS; + +	/* Enable CRS on TX. This must be set for half-duplex operation. */ +	ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); +	if (ret_val) +		return ret_val; +  	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; -#if 0  	/* Options:  	 *   MDI/MDI-X = 0 (default)  	 *   0 - Auto for all speeds @@ -1210,6 +2750,7 @@ e1000_setup_copper_link(struct eth_device *nic)  	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)  	 */  	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; +  	switch (hw->mdix) {  	case 1:  		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; @@ -1225,68 +2766,75 @@ e1000_setup_copper_link(struct eth_device *nic)  		phy_data |= M88E1000_PSCR_AUTO_X_MODE;  		break;  	} -#else -	phy_data |= M88E1000_PSCR_AUTO_X_MODE; -#endif -#if 0  	/* Options:  	 *   disable_polarity_correction = 0 (default) -	 *	 Automatic Correction for Reversed Cable Polarity +	 *       Automatic Correction for Reversed Cable Polarity  	 *   0 - Disabled  	 *   1 - Enabled  	 */  	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; -	if (hw->disable_polarity_correction == 1) -		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; -#else -	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; -#endif -	if (e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; -	} +	ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); +	if (ret_val) +		return ret_val; -	/* Force TX_CLK in the Extended PHY Specific Control Register -	 * to 25MHz clock. -	 */ -	if (e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} -	phy_data |= M88E1000_EPSCR_TX_CLK_25; -	/* Configure Master and Slave downshift values */ -	phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | -		      M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); -	phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | -		     M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); -	if (e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; +	if (hw->phy_revision < M88E1011_I_REV_4) { +		/* Force TX_CLK in the Extended PHY Specific Control Register +		 * to 25MHz clock. +		 */ +		ret_val = e1000_read_phy_reg(hw, +				M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data |= M88E1000_EPSCR_TX_CLK_25; + +		if ((hw->phy_revision == E1000_REVISION_2) && +			(hw->phy_id == M88E1111_I_PHY_ID)) { +			/* Vidalia Phy, set the downshift counter to 5x */ +			phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK); +			phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X; +			ret_val = e1000_write_phy_reg(hw, +					M88E1000_EXT_PHY_SPEC_CTRL, phy_data); +			if (ret_val) +				return ret_val; +		} else { +			/* Configure Master and Slave downshift values */ +			phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK +					| M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); +			phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X +					| M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); +			ret_val = e1000_write_phy_reg(hw, +					M88E1000_EXT_PHY_SPEC_CTRL, phy_data); +			if (ret_val) +				return ret_val; +		}  	}  	/* SW Reset the PHY so all changes take effect */  	ret_val = e1000_phy_reset(hw); -	if (ret_val < 0) { +	if (ret_val) {  		DEBUGOUT("Error Resetting the PHY\n");  		return ret_val;  	} -	/* Options: -	 *   autoneg = 1 (default) -	 *	PHY will advertise value(s) parsed from -	 *	autoneg_advertised and fc -	 *   autoneg = 0 -	 *	PHY will be set to 10H, 10F, 100H, or 100F -	 *	depending on value parsed from forced_speed_duplex. -	 */ +	return E1000_SUCCESS; +} + +/******************************************************************** +* Setup auto-negotiation and flow control advertisements, +* and then perform auto-negotiation. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_autoneg(struct e1000_hw *hw) +{ +	int32_t ret_val; +	uint16_t phy_data; + +	DEBUGFUNC(); -	/* Is autoneg enabled?	This is enabled by default or by software override. -	 * If so, call e1000_phy_setup_autoneg routine to parse the -	 * autoneg_advertised and fc options. If autoneg is NOT enabled, then the -	 * user should have provided a speed/duplex override.  If so, then call -	 * e1000_phy_force_speed_duplex to parse and set this up. -	 */  	/* Perform some bounds checking on the hw->autoneg_advertised  	 * parameter.  If this variable is zero, then set it to the default.  	 */ @@ -1298,9 +2846,13 @@ e1000_setup_copper_link(struct eth_device *nic)  	if (hw->autoneg_advertised == 0)  		hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; +	/* IFE phy only supports 10/100 */ +	if (hw->phy_type == e1000_phy_ife) +		hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL; +  	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");  	ret_val = e1000_phy_setup_autoneg(hw); -	if (ret_val < 0) { +	if (ret_val) {  		DEBUGOUT("Error Setting up Auto-Negotiation\n");  		return ret_val;  	} @@ -1309,82 +2861,177 @@ e1000_setup_copper_link(struct eth_device *nic)  	/* Restart auto-negotiation by setting the Auto Neg Enable bit and  	 * the Auto Neg Restart bit in the PHY control register.  	 */ -	if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} +	ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); +	if (ret_val) +		return ret_val; +  	phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); -	if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; -	} -#if 0 +	ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); +	if (ret_val) +		return ret_val; +  	/* Does the user want to wait for Auto-Neg to complete here, or  	 * check at a later time (for example, callback routine).  	 */ +	/* If we do not wait for autonegtation to complete I +	 * do not see a valid link status. +	 * wait_autoneg_complete = 1 . +	 */  	if (hw->wait_autoneg_complete) {  		ret_val = e1000_wait_autoneg(hw); -		if (ret_val < 0) { -			DEBUGOUT -			    ("Error while waiting for autoneg to complete\n"); +		if (ret_val) { +			DEBUGOUT("Error while waiting for autoneg" +					"to complete\n");  			return ret_val;  		}  	} -#else -	/* If we do not wait for autonegtation to complete I -	 * do not see a valid link status. -	 */ -	ret_val = e1000_wait_autoneg(hw); -	if (ret_val < 0) { -		DEBUGOUT("Error while waiting for autoneg to complete\n"); + +	hw->get_link_status = TRUE; + +	return E1000_SUCCESS; +} + +/****************************************************************************** +* Config the MAC and the PHY after link is up. +*   1) Set up the MAC to the current PHY speed/duplex +*      if we are on 82543.  If we +*      are on newer silicon, we only need to configure +*      collision distance in the Transmit Control Register. +*   2) Set up flow control on the MAC to that established with +*      the link partner. +*   3) Config DSP to improve Gigabit link quality for some PHY revisions. +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +e1000_copper_link_postconfig(struct e1000_hw *hw) +{ +	int32_t ret_val; +	DEBUGFUNC(); + +	if (hw->mac_type >= e1000_82544) { +		e1000_config_collision_dist(hw); +	} else { +		ret_val = e1000_config_mac_to_phy(hw); +		if (ret_val) { +			DEBUGOUT("Error configuring MAC to PHY settings\n"); +			return ret_val; +		} +	} +	ret_val = e1000_config_fc_after_link_up(hw); +	if (ret_val) { +		DEBUGOUT("Error Configuring Flow Control\n");  		return ret_val;  	} -#endif +	return E1000_SUCCESS; +} + +/****************************************************************************** +* Detects which PHY is present and setup the speed and duplex +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int +e1000_setup_copper_link(struct eth_device *nic) +{ +	struct e1000_hw *hw = nic->priv; +	int32_t ret_val; +	uint16_t i; +	uint16_t phy_data; +	uint16_t reg_data; + +	DEBUGFUNC(); + +	switch (hw->mac_type) { +	case e1000_80003es2lan: +	case e1000_ich8lan: +		/* Set the mac to wait the maximum time between each +		 * iteration and increase the max iterations when +		 * polling the phy; this fixes erroneous timeouts at 10Mbps. */ +		ret_val = e1000_write_kmrn_reg(hw, +				GG82563_REG(0x34, 4), 0xFFFF); +		if (ret_val) +			return ret_val; +		ret_val = e1000_read_kmrn_reg(hw, +				GG82563_REG(0x34, 9), ®_data); +		if (ret_val) +			return ret_val; +		reg_data |= 0x3F; +		ret_val = e1000_write_kmrn_reg(hw, +				GG82563_REG(0x34, 9), reg_data); +		if (ret_val) +			return ret_val; +	default: +		break; +	} + +	/* Check if it is a valid PHY and set PHY mode if necessary. */ +	ret_val = e1000_copper_link_preconfig(hw); +	if (ret_val) +		return ret_val; +	switch (hw->mac_type) { +	case e1000_80003es2lan: +		/* Kumeran registers are written-only */ +		reg_data = +		E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT; +		reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING; +		ret_val = e1000_write_kmrn_reg(hw, +				E1000_KUMCTRLSTA_OFFSET_INB_CTRL, reg_data); +		if (ret_val) +			return ret_val; +		break; +	default: +		break; +	} + +	if (hw->phy_type == e1000_phy_igp || +		hw->phy_type == e1000_phy_igp_3 || +		hw->phy_type == e1000_phy_igp_2) { +		ret_val = e1000_copper_link_igp_setup(hw); +		if (ret_val) +			return ret_val; +	} else if (hw->phy_type == e1000_phy_m88) { +		ret_val = e1000_copper_link_mgp_setup(hw); +		if (ret_val) +			return ret_val; +	} else if (hw->phy_type == e1000_phy_gg82563) { +		ret_val = e1000_copper_link_ggp_setup(hw); +		if (ret_val) +			return ret_val; +	} + +	/* always auto */ +	/* Setup autoneg and flow control advertisement +	  * and perform autonegotiation */ +	ret_val = e1000_copper_link_autoneg(hw); +	if (ret_val) +		return ret_val;  	/* Check link status. Wait up to 100 microseconds for link to become  	 * valid.  	 */  	for (i = 0; i < 10; i++) { -		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { -			DEBUGOUT("PHY Read Error\n"); -			return -E1000_ERR_PHY; -		} -		if (e1000_read_phy_reg(hw, PHY_STATUS, &phy_data) < 0) { -			DEBUGOUT("PHY Read Error\n"); -			return -E1000_ERR_PHY; -		} +		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); +		if (ret_val) +			return ret_val; +		ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); +		if (ret_val) +			return ret_val; +  		if (phy_data & MII_SR_LINK_STATUS) { -			/* We have link, so we need to finish the config process: -			 *   1) Set up the MAC to the current PHY speed/duplex -			 *	if we are on 82543.  If we -			 *	are on newer silicon, we only need to configure -			 *	collision distance in the Transmit Control Register. -			 *   2) Set up flow control on the MAC to that established with -			 *	the link partner. -			 */ -			if (hw->mac_type >= e1000_82544) { -				e1000_config_collision_dist(hw); -			} else { -				ret_val = e1000_config_mac_to_phy(hw); -				if (ret_val < 0) { -					DEBUGOUT -					    ("Error configuring MAC to PHY settings\n"); -					return ret_val; -				} -			} -			ret_val = e1000_config_fc_after_link_up(hw); -			if (ret_val < 0) { -				DEBUGOUT("Error Configuring Flow Control\n"); +			/* Config the MAC and PHY after link is up */ +			ret_val = e1000_copper_link_postconfig(hw); +			if (ret_val)  				return ret_val; -			} +  			DEBUGOUT("Valid link established!!!\n"); -			return 0; +			return E1000_SUCCESS;  		}  		udelay(10);  	}  	DEBUGOUT("Unable to establish link!!!\n"); -	return -E1000_ERR_NOLINK; +	return E1000_SUCCESS;  }  /****************************************************************************** @@ -1392,25 +3039,28 @@ e1000_setup_copper_link(struct eth_device *nic)  *  * hw - Struct containing variables accessed by shared code  ******************************************************************************/ -static int +int32_t  e1000_phy_setup_autoneg(struct e1000_hw *hw)  { +	int32_t ret_val;  	uint16_t mii_autoneg_adv_reg;  	uint16_t mii_1000t_ctrl_reg;  	DEBUGFUNC();  	/* Read the MII Auto-Neg Advertisement Register (Address 4). */ -	if (e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} +	ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); +	if (ret_val) +		return ret_val; -	/* Read the MII 1000Base-T Control Register (Address 9). */ -	if (e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} +	if (hw->phy_type != e1000_phy_ife) { +		/* Read the MII 1000Base-T Control Register (Address 9). */ +		ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, +				&mii_1000t_ctrl_reg); +		if (ret_val) +			return ret_val; +	} else +		mii_1000t_ctrl_reg = 0;  	/* Need to parse both autoneg_advertised and fc and set up  	 * the appropriate PHY registers.  First we will parse for @@ -1421,7 +3071,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)  	/* First we clear all the 10/100 mb speed bits in the Auto-Neg  	 * Advertisement Register (Address 4) and the 1000 mb speed bits in -	 * the	1000Base-T Control Register (Address 9). +	 * the  1000Base-T Control Register (Address 9).  	 */  	mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;  	mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK; @@ -1517,18 +3167,20 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)  		return -E1000_ERR_CONFIG;  	} -	if (e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; -	} +	ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); +	if (ret_val) +		return ret_val;  	DEBUGOUT("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); -	if (e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; +	if (hw->phy_type != e1000_phy_ife) { +		ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, +				mii_1000t_ctrl_reg); +		if (ret_val) +			return ret_val;  	} -	return 0; + +	return E1000_SUCCESS;  }  /****************************************************************************** @@ -1542,12 +3194,19 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)  static void  e1000_config_collision_dist(struct e1000_hw *hw)  { -	uint32_t tctl; +	uint32_t tctl, coll_dist; + +	DEBUGFUNC(); + +	if (hw->mac_type < e1000_82543) +		coll_dist = E1000_COLLISION_DISTANCE_82542; +	else +		coll_dist = E1000_COLLISION_DISTANCE;  	tctl = E1000_READ_REG(hw, TCTL);  	tctl &= ~E1000_TCTL_COLD; -	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; +	tctl |= coll_dist << E1000_COLD_SHIFT;  	E1000_WRITE_REG(hw, TCTL, tctl);  	E1000_WRITE_FLUSH(hw); @@ -1681,7 +3340,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)   * based on the flow control negotiated by the PHY. In TBI mode, the TFCE   * and RFCE bits will be automaticaly set to the negotiated flow control mode.   *****************************************************************************/ -static int +static int32_t  e1000_config_fc_after_link_up(struct e1000_hw *hw)  {  	int32_t ret_val; @@ -1697,7 +3356,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)  	 * so we had to force link.  In this case, we need to force the  	 * configuration of the MAC to match the "fc" parameter.  	 */ -	if ((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) { +	if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) +		|| ((hw->media_type == e1000_media_type_internal_serdes) +		&& (hw->autoneg_failed)) +		|| ((hw->media_type == e1000_media_type_copper) +		&& (!hw->autoneg))) {  		ret_val = e1000_force_mac_fc(hw);  		if (ret_val < 0) {  			DEBUGOUT("Error forcing flow control settings\n"); @@ -1881,7 +3544,7 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)  			    ("Copper PHY and Auto Neg has not completed.\r\n");  		}  	} -	return 0; +	return E1000_SUCCESS;  }  /****************************************************************************** @@ -2070,17 +3733,92 @@ e1000_check_for_link(struct eth_device *nic)  }  /****************************************************************************** +* Configure the MAC-to-PHY interface for 10/100Mbps +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex) +{ +	int32_t ret_val = E1000_SUCCESS; +	uint32_t tipg; +	uint16_t reg_data; + +	DEBUGFUNC(); + +	reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT; +	ret_val = e1000_write_kmrn_reg(hw, +			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data); +	if (ret_val) +		return ret_val; + +	/* Configure Transmit Inter-Packet Gap */ +	tipg = E1000_READ_REG(hw, TIPG); +	tipg &= ~E1000_TIPG_IPGT_MASK; +	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100; +	E1000_WRITE_REG(hw, TIPG, tipg); + +	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); + +	if (ret_val) +		return ret_val; + +	if (duplex == HALF_DUPLEX) +		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; +	else +		reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; + +	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); + +	return ret_val; +} + +static int32_t +e1000_configure_kmrn_for_1000(struct e1000_hw *hw) +{ +	int32_t ret_val = E1000_SUCCESS; +	uint16_t reg_data; +	uint32_t tipg; + +	DEBUGFUNC(); + +	reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT; +	ret_val = e1000_write_kmrn_reg(hw, +			E1000_KUMCTRLSTA_OFFSET_HD_CTRL, reg_data); +	if (ret_val) +		return ret_val; + +	/* Configure Transmit Inter-Packet Gap */ +	tipg = E1000_READ_REG(hw, TIPG); +	tipg &= ~E1000_TIPG_IPGT_MASK; +	tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000; +	E1000_WRITE_REG(hw, TIPG, tipg); + +	ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); + +	if (ret_val) +		return ret_val; + +	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; +	ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); + +	return ret_val; +} + +/******************************************************************************   * Detects the current speed and duplex settings of the hardware.   *   * hw - Struct containing variables accessed by shared code   * speed - Speed of the connection   * duplex - Duplex setting of the connection   *****************************************************************************/ -static void -e1000_get_speed_and_duplex(struct e1000_hw *hw, -			   uint16_t * speed, uint16_t * duplex) +static int +e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, +		uint16_t *duplex)  {  	uint32_t status; +	int32_t ret_val; +	uint16_t phy_data;  	DEBUGFUNC(); @@ -2109,6 +3847,41 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw,  		*speed = SPEED_1000;  		*duplex = FULL_DUPLEX;  	} + +	/* IGP01 PHY may advertise full duplex operation after speed downgrade +	 * even if it is operating at half duplex.  Here we set the duplex +	 * settings to match the duplex in the link partner's capabilities. +	 */ +	if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) { +		ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data); +		if (ret_val) +			return ret_val; + +		if (!(phy_data & NWAY_ER_LP_NWAY_CAPS)) +			*duplex = HALF_DUPLEX; +		else { +			ret_val = e1000_read_phy_reg(hw, +					PHY_LP_ABILITY, &phy_data); +			if (ret_val) +				return ret_val; +			if ((*speed == SPEED_100 && +				!(phy_data & NWAY_LPAR_100TX_FD_CAPS)) +				|| (*speed == SPEED_10 +				&& !(phy_data & NWAY_LPAR_10T_FD_CAPS))) +				*duplex = HALF_DUPLEX; +		} +	} + +	if ((hw->mac_type == e1000_80003es2lan) && +		(hw->media_type == e1000_media_type_copper)) { +		if (*speed == SPEED_1000) +			ret_val = e1000_configure_kmrn_for_1000(hw); +		else +			ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex); +		if (ret_val) +			return ret_val; +	} +	return E1000_SUCCESS;  }  /****************************************************************************** @@ -2429,30 +4202,132 @@ e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data)  }  /****************************************************************************** + * Checks if PHY reset is blocked due to SOL/IDER session, for example. + * Returning E1000_BLK_PHY_RESET isn't necessarily an error.  But it's up to + * the caller to figure out how to deal with it. + * + * hw - Struct containing variables accessed by shared code + * + * returns: - E1000_BLK_PHY_RESET + *            E1000_SUCCESS + * + *****************************************************************************/ +int32_t +e1000_check_phy_reset_block(struct e1000_hw *hw) +{ +	uint32_t manc = 0; +	uint32_t fwsm = 0; + +	if (hw->mac_type == e1000_ich8lan) { +		fwsm = E1000_READ_REG(hw, FWSM); +		return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS +						: E1000_BLK_PHY_RESET; +	} + +	if (hw->mac_type > e1000_82547_rev_2) +		manc = E1000_READ_REG(hw, MANC); +	return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? +		E1000_BLK_PHY_RESET : E1000_SUCCESS; +} + +/*************************************************************************** + * Checks if the PHY configuration is done + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to reset MAC + *            E1000_SUCCESS at any other case. + * + ***************************************************************************/ +static int32_t +e1000_get_phy_cfg_done(struct e1000_hw *hw) +{ +	int32_t timeout = PHY_CFG_TIMEOUT; +	uint32_t cfg_mask = E1000_EEPROM_CFG_DONE; + +	DEBUGFUNC(); + +	switch (hw->mac_type) { +	default: +		mdelay(10); +		break; +	case e1000_80003es2lan: +		/* Separate *_CFG_DONE_* bit for each port */ +		if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) +			cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1; +	/* Fall Through */ +	case e1000_82571: +	case e1000_82572: +		while (timeout) { +			if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask) +				break; +			else +				mdelay(1); +			timeout--; +		} +		if (!timeout) { +			DEBUGOUT("MNG configuration cycle has not " +					"completed.\n"); +			return -E1000_ERR_RESET; +		} +		break; +	} + +	return E1000_SUCCESS; +} + +/******************************************************************************  * Returns the PHY to the power-on reset state  *  * hw - Struct containing variables accessed by shared code  ******************************************************************************/ -static void +int32_t  e1000_phy_hw_reset(struct e1000_hw *hw)  { -	uint32_t ctrl; -	uint32_t ctrl_ext; +	uint32_t ctrl, ctrl_ext; +	uint32_t led_ctrl; +	int32_t ret_val; +	uint16_t swfw;  	DEBUGFUNC(); +	/* In the case of the phy reset being blocked, it's not an error, we +	 * simply return success without performing the reset. */ +	ret_val = e1000_check_phy_reset_block(hw); +	if (ret_val) +		return E1000_SUCCESS; +  	DEBUGOUT("Resetting Phy...\n");  	if (hw->mac_type > e1000_82543) { +		if ((hw->mac_type == e1000_80003es2lan) && +			(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) { +			swfw = E1000_SWFW_PHY1_SM; +		} else { +			swfw = E1000_SWFW_PHY0_SM; +		} +		if (e1000_swfw_sync_acquire(hw, swfw)) { +			DEBUGOUT("Unable to acquire swfw sync\n"); +			return -E1000_ERR_SWFW_SYNC; +		}  		/* Read the device control register and assert the E1000_CTRL_PHY_RST  		 * bit. Then, take it out of reset.  		 */  		ctrl = E1000_READ_REG(hw, CTRL);  		E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);  		E1000_WRITE_FLUSH(hw); -		mdelay(10); + +		if (hw->mac_type < e1000_82571) +			udelay(10); +		else +			udelay(100); +  		E1000_WRITE_REG(hw, CTRL, ctrl);  		E1000_WRITE_FLUSH(hw); + +		if (hw->mac_type >= e1000_82571) +			mdelay(10); +  	} else {  		/* Read the Extended Device Control Register, assert the PHY_RESET_DIR  		 * bit to put the PHY into reset. Then, take it out of reset. @@ -2468,6 +4343,127 @@ e1000_phy_hw_reset(struct e1000_hw *hw)  		E1000_WRITE_FLUSH(hw);  	}  	udelay(150); + +	if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { +		/* Configure activity LED after PHY reset */ +		led_ctrl = E1000_READ_REG(hw, LEDCTL); +		led_ctrl &= IGP_ACTIVITY_LED_MASK; +		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); +		E1000_WRITE_REG(hw, LEDCTL, led_ctrl); +	} + +	/* Wait for FW to finish PHY configuration. */ +	ret_val = e1000_get_phy_cfg_done(hw); +	if (ret_val != E1000_SUCCESS) +		return ret_val; + +	return ret_val; +} + +/****************************************************************************** + * IGP phy init script - initializes the GbE PHY + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +static void +e1000_phy_init_script(struct e1000_hw *hw) +{ +	uint32_t ret_val; +	uint16_t phy_saved_data; +	DEBUGFUNC(); + +	if (hw->phy_init_script) { +		mdelay(20); + +		/* Save off the current value of register 0x2F5B to be +		 * restored at the end of this routine. */ +		ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + +		/* Disabled the PHY transmitter */ +		e1000_write_phy_reg(hw, 0x2F5B, 0x0003); + +		mdelay(20); + +		e1000_write_phy_reg(hw, 0x0000, 0x0140); + +		mdelay(5); + +		switch (hw->mac_type) { +		case e1000_82541: +		case e1000_82547: +			e1000_write_phy_reg(hw, 0x1F95, 0x0001); + +			e1000_write_phy_reg(hw, 0x1F71, 0xBD21); + +			e1000_write_phy_reg(hw, 0x1F79, 0x0018); + +			e1000_write_phy_reg(hw, 0x1F30, 0x1600); + +			e1000_write_phy_reg(hw, 0x1F31, 0x0014); + +			e1000_write_phy_reg(hw, 0x1F32, 0x161C); + +			e1000_write_phy_reg(hw, 0x1F94, 0x0003); + +			e1000_write_phy_reg(hw, 0x1F96, 0x003F); + +			e1000_write_phy_reg(hw, 0x2010, 0x0008); +			break; + +		case e1000_82541_rev_2: +		case e1000_82547_rev_2: +			e1000_write_phy_reg(hw, 0x1F73, 0x0099); +			break; +		default: +			break; +		} + +		e1000_write_phy_reg(hw, 0x0000, 0x3300); + +		mdelay(20); + +		/* Now enable the transmitter */ +		e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); + +		if (hw->mac_type == e1000_82547) { +			uint16_t fused, fine, coarse; + +			/* Move to analog registers page */ +			e1000_read_phy_reg(hw, +				IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); + +			if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { +				e1000_read_phy_reg(hw, +					IGP01E1000_ANALOG_FUSE_STATUS, &fused); + +				fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; +				coarse = fused +					& IGP01E1000_ANALOG_FUSE_COARSE_MASK; + +				if (coarse > +					IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { +					coarse -= +					IGP01E1000_ANALOG_FUSE_COARSE_10; +					fine -= IGP01E1000_ANALOG_FUSE_FINE_1; +				} else if (coarse +					== IGP01E1000_ANALOG_FUSE_COARSE_THRESH) +					fine -= IGP01E1000_ANALOG_FUSE_FINE_10; + +				fused = (fused +					& IGP01E1000_ANALOG_FUSE_POLY_MASK) | +					(fine +					& IGP01E1000_ANALOG_FUSE_FINE_MASK) | +					(coarse +					& IGP01E1000_ANALOG_FUSE_COARSE_MASK); + +				e1000_write_phy_reg(hw, +					IGP01E1000_ANALOG_FUSE_CONTROL, fused); +				e1000_write_phy_reg(hw, +					IGP01E1000_ANALOG_FUSE_BYPASS, +				IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); +			} +		} +	}  }  /****************************************************************************** @@ -2475,26 +4471,49 @@ e1000_phy_hw_reset(struct e1000_hw *hw)  *  * hw - Struct containing variables accessed by shared code  * -* Sets bit 15 of the MII Control regiser +* Sets bit 15 of the MII Control register  ******************************************************************************/ -static int +int32_t  e1000_phy_reset(struct e1000_hw *hw)  { +	int32_t ret_val;  	uint16_t phy_data;  	DEBUGFUNC(); -	if (e1000_read_phy_reg(hw, PHY_CTRL, &phy_data) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} -	phy_data |= MII_CR_RESET; -	if (e1000_write_phy_reg(hw, PHY_CTRL, phy_data) < 0) { -		DEBUGOUT("PHY Write Error\n"); -		return -E1000_ERR_PHY; +	/* In the case of the phy reset being blocked, it's not an error, we +	 * simply return success without performing the reset. */ +	ret_val = e1000_check_phy_reset_block(hw); +	if (ret_val) +		return E1000_SUCCESS; + +	switch (hw->phy_type) { +	case e1000_phy_igp: +	case e1000_phy_igp_2: +	case e1000_phy_igp_3: +	case e1000_phy_ife: +		ret_val = e1000_phy_hw_reset(hw); +		if (ret_val) +			return ret_val; +		break; +	default: +		ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); +		if (ret_val) +			return ret_val; + +		phy_data |= MII_CR_RESET; +		ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); +		if (ret_val) +			return ret_val; + +		udelay(1); +		break;  	} -	udelay(1); -	return 0; + +	if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) +		e1000_phy_init_script(hw); + +	return E1000_SUCCESS;  }  static int e1000_set_phy_type (struct e1000_hw *hw) @@ -2508,12 +4527,29 @@ static int e1000_set_phy_type (struct e1000_hw *hw)  	case M88E1000_E_PHY_ID:  	case M88E1000_I_PHY_ID:  	case M88E1011_I_PHY_ID: +	case M88E1111_I_PHY_ID:  		hw->phy_type = e1000_phy_m88;  		break;  	case IGP01E1000_I_PHY_ID:  		if (hw->mac_type == e1000_82541 || -		    hw->mac_type == e1000_82541_rev_2) { +			hw->mac_type == e1000_82541_rev_2 || +			hw->mac_type == e1000_82547 || +			hw->mac_type == e1000_82547_rev_2) {  			hw->phy_type = e1000_phy_igp; +			hw->phy_type = e1000_phy_igp; +			break; +		} +	case IGP03E1000_E_PHY_ID: +		hw->phy_type = e1000_phy_igp_3; +		break; +	case IFE_E_PHY_ID: +	case IFE_PLUS_E_PHY_ID: +	case IFE_C_E_PHY_ID: +		hw->phy_type = e1000_phy_ife; +		break; +	case GG82563_E_PHY_ID: +		if (hw->mac_type == e1000_80003es2lan) { +			hw->phy_type = e1000_phy_gg82563;  			break;  		}  		/* Fall Through */ @@ -2531,27 +4567,47 @@ static int e1000_set_phy_type (struct e1000_hw *hw)  *  * hw - Struct containing variables accessed by shared code  ******************************************************************************/ -static int +static int32_t  e1000_detect_gig_phy(struct e1000_hw *hw)  { -	int32_t phy_init_status; +	int32_t phy_init_status, ret_val;  	uint16_t phy_id_high, phy_id_low; -	int match = FALSE; +	boolean_t match = FALSE;  	DEBUGFUNC(); -	/* Read the PHY ID Registers to identify which PHY is onboard. */ -	if (e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; +	/* The 82571 firmware may still be configuring the PHY.  In this +	 * case, we cannot access the PHY until the configuration is done.  So +	 * we explicitly set the PHY values. */ +	if (hw->mac_type == e1000_82571 || +		hw->mac_type == e1000_82572) { +		hw->phy_id = IGP01E1000_I_PHY_ID; +		hw->phy_type = e1000_phy_igp_2; +		return E1000_SUCCESS;  	} + +	/* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a +	 * work- around that forces PHY page 0 to be set or the reads fail. +	 * The rest of the code in this routine uses e1000_read_phy_reg to +	 * read the PHY ID.  So for ESB-2 we need to have this set so our +	 * reads won't fail.  If the attached PHY is not a e1000_phy_gg82563, +	 * the routines below will figure this out as well. */ +	if (hw->mac_type == e1000_80003es2lan) +		hw->phy_type = e1000_phy_gg82563; + +	/* Read the PHY ID Registers to identify which PHY is onboard. */ +	ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high); +	if (ret_val) +		return ret_val; +  	hw->phy_id = (uint32_t) (phy_id_high << 16); -	udelay(2); -	if (e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low) < 0) { -		DEBUGOUT("PHY Read Error\n"); -		return -E1000_ERR_PHY; -	} +	udelay(20); +	ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low); +	if (ret_val) +		return ret_val; +  	hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK); +	hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;  	switch (hw->mac_type) {  	case e1000_82543: @@ -2564,15 +4620,38 @@ e1000_detect_gig_phy(struct e1000_hw *hw)  		break;  	case e1000_82540:  	case e1000_82545: +	case e1000_82545_rev_3:  	case e1000_82546: +	case e1000_82546_rev_3:  		if (hw->phy_id == M88E1011_I_PHY_ID)  			match = TRUE;  		break; +	case e1000_82541:  	case e1000_82541_rev_2: +	case e1000_82547: +	case e1000_82547_rev_2:  		if(hw->phy_id == IGP01E1000_I_PHY_ID)  			match = TRUE;  		break; +	case e1000_82573: +		if (hw->phy_id == M88E1111_I_PHY_ID) +			match = TRUE; +		break; +	case e1000_80003es2lan: +		if (hw->phy_id == GG82563_E_PHY_ID) +			match = TRUE; +		break; +	case e1000_ich8lan: +		if (hw->phy_id == IGP03E1000_E_PHY_ID) +			match = TRUE; +		if (hw->phy_id == IFE_E_PHY_ID) +			match = TRUE; +		if (hw->phy_id == IFE_PLUS_E_PHY_ID) +			match = TRUE; +		if (hw->phy_id == IFE_C_E_PHY_ID) +			match = TRUE; +		break;  	default:  		DEBUGOUT("Invalid MAC type %d\n", hw->mac_type);  		return -E1000_ERR_CONFIG; @@ -2588,6 +4667,60 @@ e1000_detect_gig_phy(struct e1000_hw *hw)  	return -E1000_ERR_PHY;  } +/***************************************************************************** + * Set media type and TBI compatibility. + * + * hw - Struct containing variables accessed by shared code + * **************************************************************************/ +void +e1000_set_media_type(struct e1000_hw *hw) +{ +	uint32_t status; + +	DEBUGFUNC(); + +	if (hw->mac_type != e1000_82543) { +		/* tbi_compatibility is only valid on 82543 */ +		hw->tbi_compatibility_en = FALSE; +	} + +	switch (hw->device_id) { +	case E1000_DEV_ID_82545GM_SERDES: +	case E1000_DEV_ID_82546GB_SERDES: +	case E1000_DEV_ID_82571EB_SERDES: +	case E1000_DEV_ID_82571EB_SERDES_DUAL: +	case E1000_DEV_ID_82571EB_SERDES_QUAD: +	case E1000_DEV_ID_82572EI_SERDES: +	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: +		hw->media_type = e1000_media_type_internal_serdes; +		break; +	default: +		switch (hw->mac_type) { +		case e1000_82542_rev2_0: +		case e1000_82542_rev2_1: +			hw->media_type = e1000_media_type_fiber; +			break; +		case e1000_ich8lan: +		case e1000_82573: +			/* The STATUS_TBIMODE bit is reserved or reused +			 * for the this device. +			 */ +			hw->media_type = e1000_media_type_copper; +			break; +		default: +			status = E1000_READ_REG(hw, STATUS); +			if (status & E1000_STATUS_TBIMODE) { +				hw->media_type = e1000_media_type_fiber; +				/* tbi_compatibility not valid on fiber */ +				hw->tbi_compatibility_en = FALSE; +			} else { +				hw->media_type = e1000_media_type_copper; +			} +			break; +		} +	} +} +  /**   * e1000_sw_init - Initialize general software structures (struct e1000_adapter)   * @@ -2619,6 +4752,17 @@ e1000_sw_init(struct eth_device *nic, int cardnum)  		return result;  	} +	switch (hw->mac_type) { +	default: +		break; +	case e1000_82541: +	case e1000_82547: +	case e1000_82541_rev_2: +	case e1000_82547_rev_2: +		hw->phy_init_script = 1; +		break; +	} +  	/* lan a vs. lan b settings */  	if (hw->mac_type == e1000_82546)  		/*this also works w/ multiple 82546 cards */ @@ -2634,6 +4778,7 @@ e1000_sw_init(struct eth_device *nic, int cardnum)  	hw->fc_send_xon = 1;  	/* Media type - copper or fiber */ +	e1000_set_media_type(hw);  	if (hw->mac_type >= e1000_82543) {  		uint32_t status = E1000_READ_REG(hw, STATUS); @@ -2649,22 +4794,13 @@ e1000_sw_init(struct eth_device *nic, int cardnum)  		hw->media_type = e1000_media_type_fiber;  	} +	hw->tbi_compatibility_en = TRUE; +	hw->wait_autoneg_complete = TRUE;  	if (hw->mac_type < e1000_82543)  		hw->report_tx_early = 0;  	else  		hw->report_tx_early = 1; -	hw->tbi_compatibility_en = TRUE; -#if 0 -	hw->wait_autoneg_complete = FALSE; -	hw->adaptive_ifs = TRUE; - -	/* Copper options */ -	if (hw->media_type == e1000_media_type_copper) { -		hw->mdix = AUTO_ALL_MODES; -		hw->disable_polarity_correction = FALSE; -	} -#endif  	return E1000_SUCCESS;  } @@ -2693,7 +4829,8 @@ e1000_configure_tx(struct e1000_hw *hw)  {  	unsigned long ptr;  	unsigned long tctl; -	unsigned long tipg; +	unsigned long tipg, tarc; +	uint32_t ipgr1, ipgr2;  	ptr = (u32) tx_pool;  	if (ptr & 0xf) @@ -2712,45 +4849,64 @@ e1000_configure_tx(struct e1000_hw *hw)  	tx_tail = 0;  	/* Set the default values for the Tx Inter Packet Gap timer */ +	if (hw->mac_type <= e1000_82547_rev_2 && +	    (hw->media_type == e1000_media_type_fiber || +	     hw->media_type == e1000_media_type_internal_serdes)) +		tipg = DEFAULT_82543_TIPG_IPGT_FIBER; +	else +		tipg = DEFAULT_82543_TIPG_IPGT_COPPER; + +	/* Set the default values for the Tx Inter Packet Gap timer */  	switch (hw->mac_type) {  	case e1000_82542_rev2_0:  	case e1000_82542_rev2_1:  		tipg = DEFAULT_82542_TIPG_IPGT; -		tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; -		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; +		ipgr1 = DEFAULT_82542_TIPG_IPGR1; +		ipgr2 = DEFAULT_82542_TIPG_IPGR2; +		break; +	case e1000_80003es2lan: +		ipgr1 = DEFAULT_82543_TIPG_IPGR1; +		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;  		break;  	default: -		if (hw->media_type == e1000_media_type_fiber) -			tipg = DEFAULT_82543_TIPG_IPGT_FIBER; -		else -			tipg = DEFAULT_82543_TIPG_IPGT_COPPER; -		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; -		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; +		ipgr1 = DEFAULT_82543_TIPG_IPGR1; +		ipgr2 = DEFAULT_82543_TIPG_IPGR2; +		break;  	} +	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; +	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;  	E1000_WRITE_REG(hw, TIPG, tipg); -#if 0 -	/* Set the Tx Interrupt Delay register */ -	E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay); -	if (hw->mac_type >= e1000_82540) -		E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay); -#endif  	/* Program the Transmit Control Register */  	tctl = E1000_READ_REG(hw, TCTL);  	tctl &= ~E1000_TCTL_CT;  	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |  	    (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); -	E1000_WRITE_REG(hw, TCTL, tctl); + +	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) { +		tarc = E1000_READ_REG(hw, TARC0); +		/* set the speed mode bit, we'll clear it if we're not at +		 * gigabit link later */ +		/* git bit can be set to 1*/ +	} else if (hw->mac_type == e1000_80003es2lan) { +		tarc = E1000_READ_REG(hw, TARC0); +		tarc |= 1; +		E1000_WRITE_REG(hw, TARC0, tarc); +		tarc = E1000_READ_REG(hw, TARC1); +		tarc |= 1; +		E1000_WRITE_REG(hw, TARC1, tarc); +	} +  	e1000_config_collision_dist(hw); -#if 0 -	/* Setup Transmit Descriptor Settings for this adapter */ -	adapter->txd_cmd = E1000_TXD_CMD_IFCS | E1000_TXD_CMD_IDE; +	/* Setup Transmit Descriptor Settings for eop descriptor */ +	hw->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; -	if (adapter->hw.report_tx_early == 1) -		adapter->txd_cmd |= E1000_TXD_CMD_RS; +	/* Need to set up RS bit */ +	if (hw->mac_type < e1000_82543) +		hw->txd_cmd |= E1000_TXD_CMD_RPS;  	else -		adapter->txd_cmd |= E1000_TXD_CMD_RPS; -#endif +		hw->txd_cmd |= E1000_TXD_CMD_RS; +	E1000_WRITE_REG(hw, TCTL, tctl);  }  /** @@ -2766,8 +4922,9 @@ e1000_setup_rctl(struct e1000_hw *hw)  	rctl &= ~(3 << E1000_RCTL_MO_SHIFT); -	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF;	/* | -												   (hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */ +	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO +		| E1000_RCTL_RDMTS_HALF;	/* | +			(hw.mc_filter_type << E1000_RCTL_MO_SHIFT); */  	if (hw->tbi_compatibility_on == 1)  		rctl |= E1000_RCTL_SBP; @@ -2775,26 +4932,8 @@ e1000_setup_rctl(struct e1000_hw *hw)  		rctl &= ~E1000_RCTL_SBP;  	rctl &= ~(E1000_RCTL_SZ_4096); -#if 0 -	switch (adapter->rx_buffer_len) { -	case E1000_RXBUFFER_2048: -	default: -#endif  		rctl |= E1000_RCTL_SZ_2048;  		rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); -#if 0 -		break; -	case E1000_RXBUFFER_4096: -		rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE; -		break; -	case E1000_RXBUFFER_8192: -		rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE; -		break; -	case E1000_RXBUFFER_16384: -		rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE; -		break; -	} -#endif  	E1000_WRITE_REG(hw, RCTL, rctl);  } @@ -2808,23 +4947,12 @@ static void  e1000_configure_rx(struct e1000_hw *hw)  {  	unsigned long ptr; -	unsigned long rctl; -#if 0 -	unsigned long rxcsum; -#endif +	unsigned long rctl, ctrl_ext;  	rx_tail = 0;  	/* make sure receives are disabled while setting up the descriptors */  	rctl = E1000_READ_REG(hw, RCTL);  	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); -#if 0 -	/* set the Receive Delay Timer Register */ - -	E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay); -#endif  	if (hw->mac_type >= e1000_82540) { -#if 0 -		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay); -#endif  		/* Set the interrupt throttling rate.  Value is calculated  		 * as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns) */  #define MAX_INTS_PER_SEC	8000 @@ -2832,6 +4960,13 @@ e1000_configure_rx(struct e1000_hw *hw)  		E1000_WRITE_REG(hw, ITR, DEFAULT_ITR);  	} +	if (hw->mac_type >= e1000_82571) { +		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); +		/* Reset delay timers after every interrupt */ +		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; +		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); +		E1000_WRITE_FLUSH(hw); +	}  	/* Setup the Base and Length of the Rx Descriptor Ring */  	ptr = (u32) rx_pool;  	if (ptr & 0xf) @@ -2845,14 +4980,6 @@ e1000_configure_rx(struct e1000_hw *hw)  	/* Setup the HW Rx Head and Tail Descriptor Pointers */  	E1000_WRITE_REG(hw, RDH, 0);  	E1000_WRITE_REG(hw, RDT, 0); -#if 0 -	/* Enable 82543 Receive Checksum Offload for TCP and UDP */ -	if ((adapter->hw.mac_type >= e1000_82543) && (adapter->rx_csum == TRUE)) { -		rxcsum = E1000_READ_REG(hw, RXCSUM); -		rxcsum |= E1000_RXCSUM_TUOFL; -		E1000_WRITE_REG(hw, RXCSUM, rxcsum); -	} -#endif  	/* Enable Receives */  	E1000_WRITE_REG(hw, RCTL, rctl); @@ -2891,11 +5018,11 @@ e1000_transmit(struct eth_device *nic, volatile void *packet, int length)  	tx_tail = (tx_tail + 1) % 8;  	txp->buffer_addr = cpu_to_le64(virt_to_bus(packet)); -	txp->lower.data = cpu_to_le32(E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP | -				      E1000_TXD_CMD_IFCS | length); +	txp->lower.data = cpu_to_le32(hw->txd_cmd | length);  	txp->upper.data = 0;  	E1000_WRITE_REG(hw, TDT, tx_tail); +	E1000_WRITE_FLUSH(hw);  	while (!(le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD)) {  		if (i++ > TOUT_LOOP) {  			DEBUGOUT("e1000: tx timeout\n"); @@ -2972,6 +5099,37 @@ e1000_init(struct eth_device *nic, bd_t * bis)  	return 1;  } +/****************************************************************************** + * Gets the current PCI bus type of hardware + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +void e1000_get_bus_type(struct e1000_hw *hw) +{ +	uint32_t status; + +	switch (hw->mac_type) { +	case e1000_82542_rev2_0: +	case e1000_82542_rev2_1: +		hw->bus_type = e1000_bus_type_pci; +		break; +	case e1000_82571: +	case e1000_82572: +	case e1000_82573: +	case e1000_80003es2lan: +		hw->bus_type = e1000_bus_type_pci_express; +		break; +	case e1000_ich8lan: +		hw->bus_type = e1000_bus_type_pci_express; +		break; +	default: +		status = E1000_READ_REG(hw, STATUS); +		hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? +				e1000_bus_type_pcix : e1000_bus_type_pci; +		break; +	} +} +  /**************************************************************************  PROBE - Look for an adapter, this routine's visible to the outside  You should omit the last argument struct pci_device * for a non-PCI NIC @@ -3017,14 +5175,10 @@ e1000_initialize(bd_t * bis)  		sprintf(nic->name, "e1000#%d", card_number);  		/* Are these variables needed? */ -#if 0 -		hw->fc = e1000_fc_none; -		hw->original_fc = e1000_fc_none; -#else  		hw->fc = e1000_fc_default;  		hw->original_fc = e1000_fc_default; -#endif  		hw->autoneg_failed = 0; +		hw->autoneg = 1;  		hw->get_link_status = TRUE;  		hw->hw_addr = (typeof(hw->hw_addr)) iobase;  		hw->mac_type = e1000_undefined; @@ -3035,7 +5189,16 @@ e1000_initialize(bd_t * bis)  			free(nic);  			return 0;  		} +		if (e1000_check_phy_reset_block(hw)) +			printf("phy reset block error \n"); +		e1000_reset_hw(hw);  #if !(defined(CONFIG_AP1000) || defined(CONFIG_MVBC_1G)) +		if (e1000_init_eeprom_params(hw)) { +			printf("The EEPROM Checksum Is Not Valid\n"); +			free(hw); +			free(nic); +			return 0; +		}  		if (e1000_validate_eeprom_checksum(nic) < 0) {  			printf("The EEPROM Checksum Is Not Valid\n");  			free(hw); @@ -3045,7 +5208,8 @@ e1000_initialize(bd_t * bis)  #endif  		e1000_read_mac_addr(nic); -		E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA); +		/* get the bus type information */ +		e1000_get_bus_type(hw);  		printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n",  		       nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2], diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 08042a8cc..eb0804b41 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -71,9 +71,18 @@ typedef enum {  	e1000_82544,  	e1000_82540,  	e1000_82545, +	e1000_82545_rev_3,  	e1000_82546, +	e1000_82546_rev_3,  	e1000_82541,  	e1000_82541_rev_2, +	e1000_82547, +	e1000_82547_rev_2, +	e1000_82571, +	e1000_82572, +	e1000_82573, +	e1000_80003es2lan, +	e1000_ich8lan,  	e1000_num_macs  } e1000_mac_type; @@ -81,10 +90,21 @@ typedef enum {  typedef enum {  	e1000_media_type_copper = 0,  	e1000_media_type_fiber = 1, +	e1000_media_type_internal_serdes = 2,  	e1000_num_media_types  } e1000_media_type;  typedef enum { +	e1000_eeprom_uninitialized = 0, +	e1000_eeprom_spi, +	e1000_eeprom_microwire, +	e1000_eeprom_flash, +	e1000_eeprom_ich8, +	e1000_eeprom_none, /* No NVM support */ +	e1000_num_eeprom_types +} e1000_eeprom_type; + +typedef enum {  	e1000_10_half = 0,  	e1000_10_full = 1,  	e1000_100_half = 2, @@ -109,7 +129,9 @@ typedef enum {  typedef enum {  	e1000_bus_type_unknown = 0,  	e1000_bus_type_pci, -	e1000_bus_type_pcix +	e1000_bus_type_pcix, +	e1000_bus_type_pci_express, +	e1000_bus_type_reserved  } e1000_bus_type;  /* PCI bus speeds */ @@ -172,10 +194,13 @@ typedef enum {  } e1000_1000t_rx_status;  typedef enum { -    e1000_phy_m88 = 0, -    e1000_phy_igp, -    e1000_phy_igp_2, -    e1000_phy_undefined = 0xFF +	e1000_phy_m88 = 0, +	e1000_phy_igp, +	e1000_phy_igp_2, +	e1000_phy_gg82563, +	e1000_phy_igp_3, +	e1000_phy_ife, +	e1000_phy_undefined = 0xFF  } e1000_phy_type;  struct e1000_phy_info { @@ -207,6 +232,7 @@ struct e1000_phy_stats {  #define E1000_ERR_MASTER_REQUESTS_PENDING	10  #define E1000_ERR_HOST_INTERFACE_COMMAND	11  #define E1000_BLK_PHY_RESET			12 +#define E1000_ERR_SWFW_SYNC 			13  /* PCI Device IDs */  #define E1000_DEV_ID_82542	    0x1000 @@ -217,14 +243,151 @@ struct e1000_phy_stats {  #define E1000_DEV_ID_82544GC_COPPER 0x100C  #define E1000_DEV_ID_82544GC_LOM    0x100D  #define E1000_DEV_ID_82540EM	    0x100E -#define E1000_DEV_ID_82540EM_LOM    0x1015 -#define E1000_DEV_ID_82545GM_COPPER 0x1026 -#define E1000_DEV_ID_82545EM_COPPER 0x100F -#define E1000_DEV_ID_82545EM_FIBER  0x1011 -#define E1000_DEV_ID_82546EB_COPPER 0x1010 -#define E1000_DEV_ID_82546EB_FIBER  0x1012 -#define E1000_DEV_ID_82541ER	    0x1078 -#define E1000_DEV_ID_82541GI_LF	    0x107C +#define E1000_DEV_ID_82540EM_LOM         0x1015 +#define E1000_DEV_ID_82540EP_LOM         0x1016 +#define E1000_DEV_ID_82540EP             0x1017 +#define E1000_DEV_ID_82540EP_LP          0x101E +#define E1000_DEV_ID_82545EM_COPPER      0x100F +#define E1000_DEV_ID_82545EM_FIBER       0x1011 +#define E1000_DEV_ID_82545GM_COPPER      0x1026 +#define E1000_DEV_ID_82545GM_FIBER       0x1027 +#define E1000_DEV_ID_82545GM_SERDES      0x1028 +#define E1000_DEV_ID_82546EB_COPPER      0x1010 +#define E1000_DEV_ID_82546EB_FIBER       0x1012 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D +#define E1000_DEV_ID_82541EI             0x1013 +#define E1000_DEV_ID_82541EI_MOBILE      0x1018 +#define E1000_DEV_ID_82541ER_LOM         0x1014 +#define E1000_DEV_ID_82541ER             0x1078 +#define E1000_DEV_ID_82547GI             0x1075 +#define E1000_DEV_ID_82541GI             0x1076 +#define E1000_DEV_ID_82541GI_MOBILE      0x1077 +#define E1000_DEV_ID_82541GI_LF          0x107C +#define E1000_DEV_ID_82546GB_COPPER      0x1079 +#define E1000_DEV_ID_82546GB_FIBER       0x107A +#define E1000_DEV_ID_82546GB_SERDES      0x107B +#define E1000_DEV_ID_82546GB_PCIE        0x108A +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 +#define E1000_DEV_ID_82547EI             0x1019 +#define E1000_DEV_ID_82547EI_MOBILE      0x101A +#define E1000_DEV_ID_82571EB_COPPER      0x105E +#define E1000_DEV_ID_82571EB_FIBER       0x105F +#define E1000_DEV_ID_82571EB_SERDES      0x1060 +#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 +#define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5 +#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA +#define E1000_DEV_ID_82572EI_COPPER      0x107D +#define E1000_DEV_ID_82572EI_FIBER       0x107E +#define E1000_DEV_ID_82572EI_SERDES      0x107F +#define E1000_DEV_ID_82572EI             0x10B9 +#define E1000_DEV_ID_82573E              0x108B +#define E1000_DEV_ID_82573E_IAMT         0x108C +#define E1000_DEV_ID_82573L              0x109A +#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096 +#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098 +#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT     0x10BA +#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT     0x10BB + +#define E1000_DEV_ID_ICH8_IGP_M_AMT      0x1049 +#define E1000_DEV_ID_ICH8_IGP_AMT        0x104A +#define E1000_DEV_ID_ICH8_IGP_C          0x104B +#define E1000_DEV_ID_ICH8_IFE            0x104C +#define E1000_DEV_ID_ICH8_IFE_GT         0x10C4 +#define E1000_DEV_ID_ICH8_IFE_G          0x10C5 +#define E1000_DEV_ID_ICH8_IGP_M          0x104D + +#define IGP03E1000_E_PHY_ID  0x02A80390 +#define IFE_E_PHY_ID         0x02A80330 /* 10/100 PHY */ +#define IFE_PLUS_E_PHY_ID    0x02A80320 +#define IFE_C_E_PHY_ID       0x02A80310 + +#define IFE_PHY_EXTENDED_STATUS_CONTROL   0x10  /* 100BaseTx Extended Status, +						   Control and Address */ +#define IFE_PHY_SPECIAL_CONTROL           0x11  /* 100BaseTx PHY special +						   control register */ +#define IFE_PHY_RCV_FALSE_CARRIER         0x13  /* 100BaseTx Receive False +						   Carrier Counter */ +#define IFE_PHY_RCV_DISCONNECT            0x14  /* 100BaseTx Receive Disconnet +						   Counter */ +#define IFE_PHY_RCV_ERROT_FRAME           0x15  /* 100BaseTx Receive Error +						   Frame Counter */ +#define IFE_PHY_RCV_SYMBOL_ERR            0x16  /* Receive Symbol Error +						   Counter */ +#define IFE_PHY_PREM_EOF_ERR              0x17  /* 100BaseTx Receive +						   Premature End Of Frame +						   Error Counter */ +#define IFE_PHY_RCV_EOF_ERR               0x18  /* 10BaseT Receive End Of +						   Frame Error Counter */ +#define IFE_PHY_TX_JABBER_DETECT          0x19  /* 10BaseT Transmit Jabber +						   Detect Counter */ +#define IFE_PHY_EQUALIZER                 0x1A  /* PHY Equalizer Control and +						   Status */ +#define IFE_PHY_SPECIAL_CONTROL_LED       0x1B  /* PHY special control and +						   LED configuration */ +#define IFE_PHY_MDIX_CONTROL              0x1C  /* MDI/MDI-X Control register */ +#define IFE_PHY_HWI_CONTROL               0x1D  /* Hardware Integrity Control +						   (HWI) */ + +#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE  0x2000  /* Defaut 1 = Disable auto +							reduced power down */ +#define IFE_PESC_100BTX_POWER_DOWN           0x0400  /* Indicates the power +							state of 100BASE-TX */ +#define IFE_PESC_10BTX_POWER_DOWN            0x0200  /* Indicates the power +							state of 10BASE-T */ +#define IFE_PESC_POLARITY_REVERSED           0x0100  /* Indicates 10BASE-T +							polarity */ +#define IFE_PESC_PHY_ADDR_MASK               0x007C  /* Bit 6:2 for sampled PHY +							address */ +#define IFE_PESC_SPEED                       0x0002  /* Auto-negotiation speed +						result 1=100Mbs, 0=10Mbs */ +#define IFE_PESC_DUPLEX                      0x0001  /* Auto-negotiation +						duplex result 1=Full, 0=Half */ +#define IFE_PESC_POLARITY_REVERSED_SHIFT     8 + +#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN   0x0100  /* 1 = Dyanmic Power Down +							disabled */ +#define IFE_PSC_FORCE_POLARITY               0x0020  /* 1=Reversed Polarity, +							0=Normal */ +#define IFE_PSC_AUTO_POLARITY_DISABLE        0x0010  /* 1=Auto Polarity +							Disabled, 0=Enabled */ +#define IFE_PSC_JABBER_FUNC_DISABLE          0x0001  /* 1=Jabber Disabled, +						0=Normal Jabber Operation */ +#define IFE_PSC_FORCE_POLARITY_SHIFT         5 +#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT  4 + +#define IFE_PMC_AUTO_MDIX                    0x0080  /* 1=enable MDI/MDI-X +						feature, default 0=disabled */ +#define IFE_PMC_FORCE_MDIX                   0x0040  /* 1=force MDIX-X, +							0=force MDI */ +#define IFE_PMC_MDIX_STATUS                  0x0020  /* 1=MDI-X, 0=MDI */ +#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010  /* Resolution algorithm +							is completed */ +#define IFE_PMC_MDIX_MODE_SHIFT              6 +#define IFE_PHC_MDIX_RESET_ALL_MASK          0x0000  /* Disable auto MDI-X */ + +#define IFE_PHC_HWI_ENABLE                   0x8000  /* Enable the HWI +							feature */ +#define IFE_PHC_ABILITY_CHECK                0x4000  /* 1= Test Passed, +							0=failed */ +#define IFE_PHC_TEST_EXEC                    0x2000  /* PHY launch test pulses +							on the wire */ +#define IFE_PHC_HIGHZ                        0x0200  /* 1 = Open Circuit */ +#define IFE_PHC_LOWZ                         0x0400  /* 1 = Short Circuit */ +#define IFE_PHC_LOW_HIGH_Z_MASK              0x0600  /* Mask for indication +						type of problem on the line */ +#define IFE_PHC_DISTANCE_MASK                0x01FF  /* Mask for distance to +				the cable problem, in 80cm granularity */ +#define IFE_PHC_RESET_ALL_MASK               0x0000  /* Disable HWI */ +#define IFE_PSCL_PROBE_MODE                  0x0020  /* LED Probe mode */ +#define IFE_PSCL_PROBE_LEDS_OFF              0x0006  /* Force LEDs 0 and 2 +							off */ +#define IFE_PSCL_PROBE_LEDS_ON               0x0007  /* Force LEDs 0 and 2 on */ + +  #define NUM_DEV_IDS 16  #define NODE_ADDRESS_SIZE 6 @@ -235,6 +398,10 @@ struct e1000_phy_stats {  #define E1000_82542_2_0_REV_ID 2  #define E1000_82542_2_1_REV_ID 3 +#define E1000_REVISION_0       0 +#define E1000_REVISION_1       1 +#define E1000_REVISION_2       2 +#define E1000_REVISION_3       3  #define SPEED_10    10  #define SPEED_100   100 @@ -522,11 +689,27 @@ struct e1000_ffvt_entry {  #define E1000_TXCW     0x00178	/* TX Configuration Word - RW */  #define E1000_RXCW     0x00180	/* RX Configuration Word - RO */  #define E1000_TCTL     0x00400	/* TX Control - RW */ +#define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */  #define E1000_TIPG     0x00410	/* TX Inter-packet gap -RW */  #define E1000_TBT      0x00448	/* TX Burst Timer - RW */  #define E1000_AIT      0x00458	/* Adaptive Interframe Spacing Throttle - RW */  #define E1000_LEDCTL   0x00E00	/* LED Control - RW */ +#define E1000_EXTCNF_CTRL  0x00F00  /* Extended Configuration Control */ +#define E1000_EXTCNF_SIZE  0x00F08  /* Extended Configuration Size */ +#define E1000_PHY_CTRL     0x00F10  /* PHY Control Register in CSR */ +#define FEXTNVM_SW_CONFIG  0x0001  #define E1000_PBA      0x01000	/* Packet Buffer Allocation - RW */ +#define E1000_PBS      0x01008  /* Packet Buffer Size */ +#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */ +#define E1000_FLASH_UPDATES 1000 +#define E1000_EEARBC   0x01024  /* EEPROM Auto Read Bus Control */ +#define E1000_FLASHT   0x01028  /* FLASH Timer Register */ +#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */ +#define E1000_FLSWCTL  0x01030  /* FLASH control register */ +#define E1000_FLSWDATA 0x01034  /* FLASH data register */ +#define E1000_FLSWCNT  0x01038  /* FLASH Access Counter */ +#define E1000_FLOP     0x0103C  /* FLASH Opcode Register */ +#define E1000_ERT      0x02008  /* Early Rx Threshold - RW */  #define E1000_FCRTL    0x02160	/* Flow Control Receive Threshold Low - RW */  #define E1000_FCRTH    0x02168	/* Flow Control Receive Threshold High - RW */  #define E1000_RDBAL    0x02800	/* RX Descriptor Base Address Low - RW */ @@ -539,6 +722,11 @@ struct e1000_ffvt_entry {  #define E1000_RADV     0x0282C	/* RX Interrupt Absolute Delay Timer - RW */  #define E1000_RSRPD    0x02C00	/* RX Small Packet Detect - RW */  #define E1000_TXDMAC   0x03000	/* TX DMA Control - RW */ +#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */ +#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */ +#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */ +#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */ +#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */  #define E1000_TDBAL    0x03800	/* TX Descriptor Base Address Low - RW */  #define E1000_TDBAH    0x03804	/* TX Descriptor Base Address High - RW */  #define E1000_TDLEN    0x03808	/* TX Descriptor Length - RW */ @@ -548,6 +736,14 @@ struct e1000_ffvt_entry {  #define E1000_TXDCTL   0x03828	/* TX Descriptor Control - RW */  #define E1000_TADV     0x0382C	/* TX Interrupt Absolute Delay Val - RW */  #define E1000_TSPMT    0x03830	/* TCP Segmentation PAD & Min Threshold - RW */ +#define E1000_TARC0    0x03840  /* TX Arbitration Count (0) */ +#define E1000_TDBAL1   0x03900  /* TX Desc Base Address Low (1) - RW */ +#define E1000_TDBAH1   0x03904  /* TX Desc Base Address High (1) - RW */ +#define E1000_TDLEN1   0x03908  /* TX Desc Length (1) - RW */ +#define E1000_TDH1     0x03910  /* TX Desc Head (1) - RW */ +#define E1000_TDT1     0x03918  /* TX Desc Tail (1) - RW */ +#define E1000_TXDCTL1  0x03928  /* TX Descriptor Control (1) - RW */ +#define E1000_TARC1    0x03940  /* TX Arbitration Count (1) */  #define E1000_CRCERRS  0x04000	/* CRC Error Count - R/clr */  #define E1000_ALGNERRC 0x04004	/* Alignment Error Count - R/clr */  #define E1000_SYMERRS  0x04008	/* Symbol Error Count - R/clr */ @@ -812,6 +1008,44 @@ struct e1000_hw_stats {  	uint64_t tsctfc;  }; +struct e1000_eeprom_info { +    e1000_eeprom_type type; +    uint16_t word_size; +    uint16_t opcode_bits; +    uint16_t address_bits; +    uint16_t delay_usec; +    uint16_t page_size; +    boolean_t use_eerd; +    boolean_t use_eewr; +}; + +typedef enum { +    e1000_smart_speed_default = 0, +    e1000_smart_speed_on, +    e1000_smart_speed_off +} e1000_smart_speed; + +typedef enum { +    e1000_dsp_config_disabled = 0, +    e1000_dsp_config_enabled, +    e1000_dsp_config_activated, +    e1000_dsp_config_undefined = 0xFF +} e1000_dsp_config; + +typedef enum { +    e1000_ms_hw_default = 0, +    e1000_ms_force_master, +    e1000_ms_force_slave, +    e1000_ms_auto +} e1000_ms_type; + +typedef enum { +    e1000_ffe_config_enabled = 0, +    e1000_ffe_config_active, +    e1000_ffe_config_blocked +} e1000_ffe_config; + +  /* Structure containing variables used by the shared code (e1000_hw.c) */  struct e1000_hw {  	pci_dev_t pdev; @@ -819,16 +1053,26 @@ struct e1000_hw {  	e1000_mac_type mac_type;  	e1000_phy_type phy_type;  	uint32_t phy_init_script; +	uint32_t txd_cmd;  	e1000_media_type media_type;  	e1000_lan_loc lan_loc;  	e1000_fc_type fc; +	e1000_bus_type bus_type;  #if 0  	e1000_bus_speed bus_speed;  	e1000_bus_width bus_width; -	e1000_bus_type bus_type;  	uint32_t io_base;  #endif +	uint32_t		asf_firmware_present; +	uint32_t		eeprom_semaphore_present; +	uint32_t		swfw_sync_present; +	uint32_t		swfwhw_semaphore_present; +	struct e1000_eeprom_info eeprom; +	e1000_ms_type		master_slave; +	e1000_ms_type		original_master_slave; +	e1000_ffe_config	ffe_config_state;  	uint32_t phy_id; +	uint32_t phy_revision;  	uint32_t phy_addr;  	uint32_t original_fc;  	uint32_t txcw; @@ -861,31 +1105,45 @@ struct e1000_hw {  	uint16_t subsystem_id;  	uint16_t subsystem_vendor_id;  	uint8_t revision_id; -#if 0  	uint8_t autoneg;  	uint8_t mdix;  	uint8_t forced_speed_duplex;  	uint8_t wait_autoneg_complete;  	uint8_t dma_fairness; -#endif  #if 0  	uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; -	boolean_t disable_polarity_correction;  #endif +	boolean_t disable_polarity_correction; +	boolean_t		speed_downgraded;  	boolean_t get_link_status;  	boolean_t tbi_compatibility_en;  	boolean_t tbi_compatibility_on; +	boolean_t		fc_strict_ieee;  	boolean_t fc_send_xon;  	boolean_t report_tx_early; +	boolean_t phy_reset_disable; +	boolean_t		initialize_hw_bits_disable;  #if 0  	boolean_t adaptive_ifs;  	boolean_t ifs_params_forced;  	boolean_t in_ifs_mode;  #endif +	e1000_smart_speed	smart_speed; +	e1000_dsp_config	dsp_config_state;  };  #define E1000_EEPROM_SWDPIN0   0x0001	/* SWDPIN 0 EEPROM Value */  #define E1000_EEPROM_LED_LOGIC 0x0020	/* Led Logic Word */ +#define E1000_EEPROM_RW_REG_DATA   16   /* Offset to data in EEPROM +					   read/write registers */ +#define E1000_EEPROM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */ +#define E1000_EEPROM_RW_REG_START  1    /* First bit for telling part to start +					   operation */ +#define E1000_EEPROM_RW_ADDR_SHIFT 2    /* Shift to the address bits */ +#define E1000_EEPROM_POLL_WRITE    1    /* Flag for polling for write +					   complete */ +#define E1000_EEPROM_POLL_READ     0    /* Flag for polling for read complete */ +#define EEPROM_RESERVED_WORD          0xFFFF  /* Register Bit Masks */  /* Device Control */ @@ -957,6 +1215,30 @@ struct e1000_hw {  #define E1000_EECD_REQ	     0x00000040	/* EEPROM Access Request */  #define E1000_EECD_GNT	     0x00000080	/* EEPROM Access Grant */  #define E1000_EECD_PRES      0x00000100	/* EEPROM Present */ +#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type +					 * (0-small, 1-large) */ + +#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */ +#ifndef E1000_EEPROM_GRANT_ATTEMPTS +#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ +#endif +#define E1000_EECD_AUTO_RD          0x00000200  /* EEPROM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* EEprom Size */ +#define E1000_EECD_SIZE_EX_SHIFT    11 +#define E1000_EECD_NVADDS    0x00018000 /* NVM Address Size */ +#define E1000_EECD_SELSHAD   0x00020000 /* Select Shadow RAM */ +#define E1000_EECD_INITSRAM  0x00040000 /* Initialize Shadow RAM */ +#define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */ +#define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */ +#define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */ +#define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */ +#define E1000_EECD_SECVAL_SHIFT      22 +#define E1000_STM_OPCODE     0xDB00 +#define E1000_HICR_FW_RESET  0xC0 + +#define E1000_SHADOW_RAM_WORDS     2048 +#define E1000_ICH_NVM_SIG_WORD     0x13 +#define E1000_ICH_NVM_SIG_MASK     0xC0  /* EEPROM Read */  #define E1000_EERD_START      0x00000001	/* Start Read */ @@ -966,14 +1248,62 @@ struct e1000_hw {  #define E1000_EERD_DATA_SHIFT 16  #define E1000_EERD_DATA_MASK  0xFFFF0000	/* Read Data */ +/* EEPROM Commands - Microwire */ +#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */ +#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */ +#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */ +#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */ + +/* EEPROM Commands - SPI */ +#define EEPROM_MAX_RETRY_SPI        5000 /* Max wait of 5ms, for RDY signal */ +#define EEPROM_READ_OPCODE_SPI      0x03  /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_SPI     0x02  /* EEPROM write opcode */ +#define EEPROM_A8_OPCODE_SPI        0x08  /* opcode bit-3 = address bit-8 */ +#define EEPROM_WREN_OPCODE_SPI      0x06  /* EEPROM set Write Enable latch */ +#define EEPROM_WRDI_OPCODE_SPI      0x04  /* EEPROM reset Write Enable latch */ +#define EEPROM_RDSR_OPCODE_SPI      0x05  /* EEPROM read Status register */ +#define EEPROM_WRSR_OPCODE_SPI      0x01  /* EEPROM write Status register */ +#define EEPROM_ERASE4K_OPCODE_SPI   0x20  /* EEPROM ERASE 4KB */ +#define EEPROM_ERASE64K_OPCODE_SPI  0xD8  /* EEPROM ERASE 64KB */ +#define EEPROM_ERASE256_OPCODE_SPI  0xDB  /* EEPROM ERASE 256B */ + +/* EEPROM Size definitions */ +#define EEPROM_WORD_SIZE_SHIFT  6 +#define EEPROM_SIZE_SHIFT       10 +#define EEPROM_SIZE_MASK        0x1C00 + +/* EEPROM Word Offsets */ +#define EEPROM_COMPAT                 0x0003 +#define EEPROM_ID_LED_SETTINGS        0x0004 +#define EEPROM_VERSION                0x0005 +#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude +						adjustment. */ +#define EEPROM_PHY_CLASS_WORD         0x0007 +#define EEPROM_INIT_CONTROL1_REG      0x000A +#define EEPROM_INIT_CONTROL2_REG      0x000F +#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010 +#define EEPROM_INIT_CONTROL3_PORT_B   0x0014 +#define EEPROM_INIT_3GIO_3            0x001A +#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020 +#define EEPROM_INIT_CONTROL3_PORT_A   0x0024 +#define EEPROM_CFG                    0x0012 +#define EEPROM_FLASH_VERSION          0x0032 +#define EEPROM_CHECKSUM_REG           0x003F + +#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */ +#define E1000_EEPROM_CFG_DONE_PORT_1  0x00080000   /* ...for second port */ +  /* Extended Device Control */  #define E1000_CTRL_EXT_GPI0_EN	 0x00000001	/* Maps SDP4 to GPI0 */  #define E1000_CTRL_EXT_GPI1_EN	 0x00000002	/* Maps SDP5 to GPI1 */  #define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN  #define E1000_CTRL_EXT_GPI2_EN	 0x00000004	/* Maps SDP6 to GPI2 */  #define E1000_CTRL_EXT_GPI3_EN	 0x00000008	/* Maps SDP7 to GPI3 */ -#define E1000_CTRL_EXT_SDP4_DATA 0x00000010	/* Value of SW Defineable Pin 4 */ -#define E1000_CTRL_EXT_SDP5_DATA 0x00000020	/* Value of SW Defineable Pin 5 */ +#define E1000_CTRL_EXT_SDP4_DATA 0x00000010	/* Value of SW Defineable +						   Pin 4 */ +#define E1000_CTRL_EXT_SDP5_DATA 0x00000020	/* Value of SW Defineable +						   Pin 5 */  #define E1000_CTRL_EXT_PHY_INT	 E1000_CTRL_EXT_SDP5_DATA  #define E1000_CTRL_EXT_SDP6_DATA 0x00000040	/* Value of SW Defineable Pin 6 */  #define E1000_CTRL_EXT_SWDPIN6	 0x00000040	/* SWDPIN 6 value */ @@ -989,6 +1319,7 @@ struct e1000_hw {  #define E1000_CTRL_EXT_EE_RST	 0x00002000	/* Reinitialize from EEPROM */  #define E1000_CTRL_EXT_IPS	 0x00004000	/* Invert Power State */  #define E1000_CTRL_EXT_SPD_BYPS  0x00008000	/* Speed Select Bypass */ +#define E1000_CTRL_EXT_RO_DIS    0x00020000 /* Relaxed Ordering disable */  #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000  #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000  #define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000 @@ -1010,6 +1341,12 @@ struct e1000_hw {  #define E1000_MDIC_INT_EN    0x20000000  #define E1000_MDIC_ERROR     0x40000000 +#define E1000_PHY_CTRL_SPD_EN                  0x00000001 +#define E1000_PHY_CTRL_D0A_LPLU                0x00000002 +#define E1000_PHY_CTRL_NOND0A_LPLU             0x00000004 +#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE      0x00000008 +#define E1000_PHY_CTRL_GBE_DISABLE             0x00000040 +#define E1000_PHY_CTRL_B2B_EN                  0x00000080  /* LED Control */  #define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F  #define E1000_LEDCTL_LED0_MODE_SHIFT 0 @@ -1153,6 +1490,12 @@ struct e1000_hw {  #define E1000_RCTL_PMCF		0x00800000	/* pass MAC control frames */  #define E1000_RCTL_BSEX		0x02000000	/* Buffer size extension */ +/* SW_W_SYNC definitions */ +#define E1000_SWFW_EEP_SM     0x0001 +#define E1000_SWFW_PHY0_SM    0x0002 +#define E1000_SWFW_PHY1_SM    0x0004 +#define E1000_SWFW_MAC_CSR_SM 0x0008 +  /* Receive Descriptor */  #define E1000_RDT_DELAY 0x0000ffff	/* Delay timer (1=1024us) */  #define E1000_RDT_FPDB	0x80000000	/* Flush descriptor block */ @@ -1173,12 +1516,14 @@ struct e1000_hw {  #define E1000_RXDCTL_GRAN    0x01000000	/* RXDCTL Granularity */  /* Transmit Descriptor Control */ -#define E1000_TXDCTL_PTHRESH 0x000000FF	/* TXDCTL Prefetch Threshold */ -#define E1000_TXDCTL_HTHRESH 0x0000FF00	/* TXDCTL Host Threshold */ -#define E1000_TXDCTL_WTHRESH 0x00FF0000	/* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_PTHRESH 0x0000003F	/* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x00003F00	/* TXDCTL Host Threshold */ +#define E1000_TXDCTL_WTHRESH 0x003F0000	/* TXDCTL Writeback Threshold */  #define E1000_TXDCTL_GRAN    0x01000000	/* TXDCTL Granularity */  #define E1000_TXDCTL_LWTHRESH 0xFE000000	/* TXDCTL Low Threshold */  #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000	/* GRAN=1, WTHRESH=1 */ +#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. +					      still to be processed. */  /* Transmit Configuration Word */  #define E1000_TXCW_FD	      0x00000020	/* TXCW full duplex */ @@ -1212,6 +1557,7 @@ struct e1000_hw {  #define E1000_TCTL_PBE	  0x00800000	/* Packet Burst Enable */  #define E1000_TCTL_RTLC   0x01000000	/* Re-transmit on late collision */  #define E1000_TCTL_NRTU   0x02000000	/* No Re-transmit on underrun */ +#define E1000_TCTL_MULR   0x10000000    /* Multiple request support */  /* Receive Checksum Control */  #define E1000_RXCSUM_PCSS_MASK 0x000000FF	/* Packet Checksum Start */ @@ -1349,9 +1695,10 @@ struct e1000_hw {  #define PBA_SIZE 4  /* Collision related configuration parameters */ -#define E1000_COLLISION_THRESHOLD	16 +#define E1000_COLLISION_THRESHOLD	0xF  #define E1000_CT_SHIFT			4 -#define E1000_COLLISION_DISTANCE	64 +#define E1000_COLLISION_DISTANCE        63 +#define E1000_COLLISION_DISTANCE_82542  64  #define E1000_FDX_COLLISION_DISTANCE	E1000_COLLISION_DISTANCE  #define E1000_HDX_COLLISION_DISTANCE	E1000_COLLISION_DISTANCE  #define E1000_GB_HDX_COLLISION_DISTANCE 512 @@ -1376,6 +1723,7 @@ struct e1000_hw {  #define DEFAULT_82542_TIPG_IPGR2 10  #define DEFAULT_82543_TIPG_IPGR2 6 +#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7  #define E1000_TIPG_IPGR2_SHIFT	20  #define E1000_TXDMAC_DPP 0x00000001 @@ -1396,6 +1744,7 @@ struct e1000_hw {  /* PBA constants */  #define E1000_PBA_16K 0x0010	/* 16KB, default TX allocation */  #define E1000_PBA_24K 0x0018 +#define E1000_PBA_38K 0x0026  #define E1000_PBA_40K 0x0028  #define E1000_PBA_48K 0x0030	/* 48KB, default RX allocation */ @@ -1537,8 +1886,22 @@ struct e1000_hw {  #define M88E1000_EXT_PHY_SPEC_CTRL	0x14	/* Extended PHY Specific Control */  #define M88E1000_RX_ERR_CNTR		0x15	/* Receive Error Counter */ +#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */ +#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */ +  #define MAX_PHY_REG_ADDRESS		0x1F	/* 5 bit address bus (0-0x1F) */ +/* M88EC018 Rev 2 specific DownShift settings */ +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X    0x0000 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X    0x0200 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X    0x0400 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X    0x0600 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X    0x0A00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X    0x0C00 +#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X    0x0E00 +  /* IGP01E1000 specifics */  #define IGP01E1000_IEEE_REGS_PAGE	0x0000  #define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300 @@ -1554,6 +1917,290 @@ struct e1000_hw {  #define IGP02E1000_PHY_POWER_MGMT	0x19  #define IGP01E1000_PHY_PAGE_SELECT	0x1F /* PHY Page Select Core Register */ +/* IGP01E1000 AGC Registers - stores the cable length values*/ +#define IGP01E1000_PHY_AGC_A        0x1172 +#define IGP01E1000_PHY_AGC_B        0x1272 +#define IGP01E1000_PHY_AGC_C        0x1472 +#define IGP01E1000_PHY_AGC_D        0x1872 + +/* IGP01E1000 Specific Port Config Register - R/W */ +#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010 +#define IGP01E1000_PSCFR_PRE_EN                0x0020 +#define IGP01E1000_PSCFR_SMART_SPEED           0x0080 +#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK    0x0100 +#define IGP01E1000_PSCFR_DISABLE_JABBER        0x0400 +#define IGP01E1000_PSCFR_DISABLE_TRANSMIT      0x2000 +/* IGP02E1000 AGC Registers for cable length values */ +#define IGP02E1000_PHY_AGC_A        0x11B1 +#define IGP02E1000_PHY_AGC_B        0x12B1 +#define IGP02E1000_PHY_AGC_C        0x14B1 +#define IGP02E1000_PHY_AGC_D        0x18B1 + +#define IGP02E1000_PM_SPD                         0x0001  /* Smart Power Down */ +#define IGP02E1000_PM_D3_LPLU                     0x0004  /* Enable LPLU in +							     non-D0a modes */ +#define IGP02E1000_PM_D0_LPLU                     0x0002  /* Enable LPLU in +							     D0a mode */ + +/* IGP01E1000 DSP Reset Register */ +#define IGP01E1000_PHY_DSP_RESET   0x1F33 +#define IGP01E1000_PHY_DSP_SET     0x1F71 +#define IGP01E1000_PHY_DSP_FFE     0x1F35 + +#define IGP01E1000_PHY_CHANNEL_NUM    4 +#define IGP02E1000_PHY_CHANNEL_NUM    4 + +#define IGP01E1000_PHY_AGC_PARAM_A    0x1171 +#define IGP01E1000_PHY_AGC_PARAM_B    0x1271 +#define IGP01E1000_PHY_AGC_PARAM_C    0x1471 +#define IGP01E1000_PHY_AGC_PARAM_D    0x1871 + +#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000 +#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000 + +#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890 +#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000 +#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004 +#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069 + +#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A +/* IGP01E1000 PCS Initialization register - stores the polarity status when + * speed = 1000 Mbps. */ +#define IGP01E1000_PHY_PCS_INIT_REG  0x00B4 +#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5 + +#define IGP01E1000_ANALOG_REGS_PAGE  0x20C0 + +/* IGP01E1000 GMII FIFO Register */ +#define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed +							* on Link-Up */ +#define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */ + +/* IGP01E1000 Analog Register */ +#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS       0x20D1 +#define IGP01E1000_ANALOG_FUSE_STATUS             0x20D0 +#define IGP01E1000_ANALOG_FUSE_CONTROL            0x20DC +#define IGP01E1000_ANALOG_FUSE_BYPASS             0x20DE + +#define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000 +#define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80 +#define IGP01E1000_ANALOG_FUSE_COARSE_MASK          0x0070 +#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED        0x0100 +#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL    0x0002 + +#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH        0x0040 +#define IGP01E1000_ANALOG_FUSE_COARSE_10            0x0010 +#define IGP01E1000_ANALOG_FUSE_FINE_1               0x0080 +#define IGP01E1000_ANALOG_FUSE_FINE_10              0x0500 + +/* IGP01E1000 Specific Port Control Register - R/W */ +#define IGP01E1000_PSCR_TP_LOOPBACK            0x0010 +#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200 +#define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400 +#define IGP01E1000_PSCR_FLIP_CHIP              0x0800 +#define IGP01E1000_PSCR_AUTO_MDIX              0x1000 +#define IGP01E1000_PSCR_FORCE_MDI_MDIX         0x2000 /* 0-MDI, 1-MDIX */ +/* GG82563 PHY Specific Status Register (Page 0, Register 16 */ +#define GG82563_PSCR_DISABLE_JABBER             0x0001 /* 1=Disable Jabber */ +#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE  0x0002 /* 1=Polarity Reversal +							  Disabled */ +#define GG82563_PSCR_POWER_DOWN                 0x0004 /* 1=Power Down */ +#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE  0x0008 /* 1=Transmitter +							  Disabled */ +#define GG82563_PSCR_CROSSOVER_MODE_MASK        0x0060 +#define GG82563_PSCR_CROSSOVER_MODE_MDI         0x0000 /* 00=Manual MDI +							  configuration */ +#define GG82563_PSCR_CROSSOVER_MODE_MDIX        0x0020 /* 01=Manual MDIX +							  configuration */ +#define GG82563_PSCR_CROSSOVER_MODE_AUTO        0x0060 /* 11=Automatic +							  crossover */ +#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE   0x0080 /* 1=Enable Extended +							  Distance */ +#define GG82563_PSCR_ENERGY_DETECT_MASK         0x0300 +#define GG82563_PSCR_ENERGY_DETECT_OFF          0x0000 /* 00,01=Off */ +#define GG82563_PSCR_ENERGY_DETECT_RX           0x0200 /* 10=Sense on Rx only +							  (Energy Detect) */ +#define GG82563_PSCR_ENERGY_DETECT_RX_TM        0x0300 /* 11=Sense and Tx NLP */ +#define GG82563_PSCR_FORCE_LINK_GOOD            0x0400 /* 1=Force Link Good */ +#define GG82563_PSCR_DOWNSHIFT_ENABLE           0x0800 /* 1=Enable Downshift */ +#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK     0x7000 +#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT    12 + +/* PHY Specific Status Register (Page 0, Register 17) */ +#define GG82563_PSSR_JABBER                0x0001 /* 1=Jabber */ +#define GG82563_PSSR_POLARITY              0x0002 /* 1=Polarity Reversed */ +#define GG82563_PSSR_LINK                  0x0008 /* 1=Link is Up */ +#define GG82563_PSSR_ENERGY_DETECT         0x0010 /* 1=Sleep, 0=Active */ +#define GG82563_PSSR_DOWNSHIFT             0x0020 /* 1=Downshift */ +#define GG82563_PSSR_CROSSOVER_STATUS      0x0040 /* 1=MDIX, 0=MDI */ +#define GG82563_PSSR_RX_PAUSE_ENABLED      0x0100 /* 1=Receive Pause Enabled */ +#define GG82563_PSSR_TX_PAUSE_ENABLED      0x0200 /* 1=Transmit Pause Enabled */ +#define GG82563_PSSR_LINK_UP               0x0400 /* 1=Link Up */ +#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */ +#define GG82563_PSSR_PAGE_RECEIVED         0x1000 /* 1=Page Received */ +#define GG82563_PSSR_DUPLEX                0x2000 /* 1-Full-Duplex */ +#define GG82563_PSSR_SPEED_MASK            0xC000 +#define GG82563_PSSR_SPEED_10MBPS          0x0000 /* 00=10Mbps */ +#define GG82563_PSSR_SPEED_100MBPS         0x4000 /* 01=100Mbps */ +#define GG82563_PSSR_SPEED_1000MBPS        0x8000 /* 10=1000Mbps */ + +/* PHY Specific Status Register 2 (Page 0, Register 19) */ +#define GG82563_PSSR2_JABBER                0x0001 /* 1=Jabber */ +#define GG82563_PSSR2_POLARITY_CHANGED      0x0002 /* 1=Polarity Changed */ +#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */ +#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT   0x0020 /* 1=Downshift Detected */ +#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE  0x0040 /* 1=Crossover Changed */ +#define GG82563_PSSR2_FALSE_CARRIER         0x0100 /* 1=False Carrier */ +#define GG82563_PSSR2_SYMBOL_ERROR          0x0200 /* 1=Symbol Error */ +#define GG82563_PSSR2_LINK_STATUS_CHANGED   0x0400 /* 1=Link Status Changed */ +#define GG82563_PSSR2_AUTO_NEG_COMPLETED    0x0800 /* 1=Auto-Neg Completed */ +#define GG82563_PSSR2_PAGE_RECEIVED         0x1000 /* 1=Page Received */ +#define GG82563_PSSR2_DUPLEX_CHANGED        0x2000 /* 1=Duplex Changed */ +#define GG82563_PSSR2_SPEED_CHANGED         0x4000 /* 1=Speed Changed */ +#define GG82563_PSSR2_AUTO_NEG_ERROR        0x8000 /* 1=Auto-Neg Error */ + +/* PHY Specific Control Register 2 (Page 0, Register 26) */ +#define GG82563_PSCR2_10BT_POLARITY_FORCE           0x0002 /* 1=Force Negative +							      Polarity */ +#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK       0x000C +#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL     0x0000 /* 00,01=Normal +							      Operation */ +#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS      0x0008 /* 10=Select 112ns +							      Sequence */ +#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS       0x000C /* 11=Select 16ns +							      Sequence */ +#define GG82563_PSCR2_REVERSE_AUTO_NEG              0x2000 /* 1=Reverse +							Auto-Negotiation */ +#define GG82563_PSCR2_1000BT_DISABLE                0x4000 /* 1=Disable +							      1000BASE-T */ +#define GG82563_PSCR2_TRANSMITER_TYPE_MASK          0x8000 +#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B      0x0000 /* 0=Class B */ +#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A      0x8000 /* 1=Class A */ + +/* MAC Specific Control Register (Page 2, Register 21) */ +/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */ +#define GG82563_MSCR_TX_CLK_MASK                    0x0007 +#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ           0x0004 +#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ           0x0005 +#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ         0x0006 +#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ          0x0007 + +#define GG82563_MSCR_ASSERT_CRS_ON_TX               0x0010 /* 1=Assert */ + +/* DSP Distance Register (Page 5, Register 26) */ +#define GG82563_DSPD_CABLE_LENGTH               0x0007 /* 0 = <50M; +							  1 = 50-80M; +							  2 = 80-110M; +							  3 = 110-140M; +							  4 = >140M */ + +/* Kumeran Mode Control Register (Page 193, Register 16) */ +#define GG82563_KMCR_PHY_LEDS_EN                    0x0020 /* 1=PHY LEDs, +							0=Kumeran Inband LEDs */ +#define GG82563_KMCR_FORCE_LINK_UP                  0x0040 /* 1=Force Link Up */ +#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT         0x0080 +#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK     0x0400 +#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT          0x0400 /* 1=6.25MHz, +							      0=0.8MHz */ +#define GG82563_KMCR_PASS_FALSE_CARRIER             0x0800 + +/* Power Management Control Register (Page 193, Register 20) */ +#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE    0x0001 /* 1=Enalbe SERDES +						Electrical Idle */ +#define GG82563_PMCR_DISABLE_PORT              0x0002 /* 1=Disable Port */ +#define GG82563_PMCR_DISABLE_SERDES            0x0004 /* 1=Disable SERDES */ +#define GG82563_PMCR_REVERSE_AUTO_NEG          0x0008 /* 1=Enable Reverse +						Auto-Negotiation */ +#define GG82563_PMCR_DISABLE_1000_NON_D0       0x0010 /* 1=Disable 1000Mbps +							 Auto-Neg in non D0 */ +#define GG82563_PMCR_DISABLE_1000              0x0020 /* 1=Disable 1000Mbps +							 Auto-Neg Always */ +#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A      0x0040 /* 1=Enable D0a +						Reverse Auto-Negotiation */ +#define GG82563_PMCR_FORCE_POWER_STATE         0x0080 /* 1=Force Power State */ +#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK    0x0300 +#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR      0x0000 /* 00=Dr */ +#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U     0x0100 /* 01=D0u */ +#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A     0x0200 /* 10=D0a */ +#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3      0x0300 /* 11=D3 */ + +/* In-Band Control Register (Page 194, Register 18) */ +#define GG82563_ICR_DIS_PADDING		0x0010 /* Disable Padding Use */ + + +/* Bits... + * 15-5: page + * 4-0: register offset + */ +#define GG82563_PAGE_SHIFT        5 +#define GG82563_REG(page, reg)    \ +	(((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS)) +#define GG82563_MIN_ALT_REG       30 + +/* GG82563 Specific Registers */ +#define GG82563_PHY_SPEC_CTRL           \ +	GG82563_REG(0, 16) /* PHY Specific Control */ +#define GG82563_PHY_SPEC_STATUS         \ +	GG82563_REG(0, 17) /* PHY Specific Status */ +#define GG82563_PHY_INT_ENABLE          \ +	GG82563_REG(0, 18) /* Interrupt Enable */ +#define GG82563_PHY_SPEC_STATUS_2       \ +	GG82563_REG(0, 19) /* PHY Specific Status 2 */ +#define GG82563_PHY_RX_ERR_CNTR         \ +	GG82563_REG(0, 21) /* Receive Error Counter */ +#define GG82563_PHY_PAGE_SELECT         \ +	GG82563_REG(0, 22) /* Page Select */ +#define GG82563_PHY_SPEC_CTRL_2         \ +	GG82563_REG(0, 26) /* PHY Specific Control 2 */ +#define GG82563_PHY_PAGE_SELECT_ALT     \ +	GG82563_REG(0, 29) /* Alternate Page Select */ +#define GG82563_PHY_TEST_CLK_CTRL       \ +	GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */ + +#define GG82563_PHY_MAC_SPEC_CTRL       \ +	GG82563_REG(2, 21) /* MAC Specific Control Register */ +#define GG82563_PHY_MAC_SPEC_CTRL_2     \ +	GG82563_REG(2, 26) /* MAC Specific Control 2 */ + +#define GG82563_PHY_DSP_DISTANCE    \ +	GG82563_REG(5, 26) /* DSP Distance */ + +/* Page 193 - Port Control Registers */ +#define GG82563_PHY_KMRN_MODE_CTRL   \ +	GG82563_REG(193, 16) /* Kumeran Mode Control */ +#define GG82563_PHY_PORT_RESET          \ +	GG82563_REG(193, 17) /* Port Reset */ +#define GG82563_PHY_REVISION_ID         \ +	GG82563_REG(193, 18) /* Revision ID */ +#define GG82563_PHY_DEVICE_ID           \ +	GG82563_REG(193, 19) /* Device ID */ +#define GG82563_PHY_PWR_MGMT_CTRL       \ +	GG82563_REG(193, 20) /* Power Management Control */ +#define GG82563_PHY_RATE_ADAPT_CTRL     \ +	GG82563_REG(193, 25) /* Rate Adaptation Control */ + +/* Page 194 - KMRN Registers */ +#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \ +	GG82563_REG(194, 16) /* FIFO's Control/Status */ +#define GG82563_PHY_KMRN_CTRL           \ +	GG82563_REG(194, 17) /* Control */ +#define GG82563_PHY_INBAND_CTRL         \ +	GG82563_REG(194, 18) /* Inband Control */ +#define GG82563_PHY_KMRN_DIAGNOSTIC     \ +	GG82563_REG(194, 19) /* Diagnostic */ +#define GG82563_PHY_ACK_TIMEOUTS        \ +	GG82563_REG(194, 20) /* Acknowledge Timeouts */ +#define GG82563_PHY_ADV_ABILITY         \ +	GG82563_REG(194, 21) /* Advertised Ability */ +#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \ +	GG82563_REG(194, 23) /* Link Partner Advertised Ability */ +#define GG82563_PHY_ADV_NEXT_PAGE       \ +	GG82563_REG(194, 24) /* Advertised Next Page */ +#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \ +	GG82563_REG(194, 25) /* Link Partner Advertised Next page */ +#define GG82563_PHY_KMRN_MISC           \ +	GG82563_REG(194, 26) /* Misc. */ +  /* PHY Control Register */  #define MII_CR_SPEED_SELECT_MSB		0x0040	/* bits 6,13: 10=1000, 01=100, 00=10 */  #define MII_CR_COLL_TEST_ENABLE		0x0080	/* Collision test enable */ @@ -1765,6 +2412,10 @@ struct e1000_hw {  #define M88E1000_12_PHY_ID		M88E1000_E_PHY_ID  #define M88E1000_14_PHY_ID		M88E1000_E_PHY_ID  #define IGP01E1000_I_PHY_ID		0x02A80380 +#define M88E1011_I_REV_4   0x04 +#define M88E1111_I_PHY_ID  0x01410CC0 +#define L1LXT971A_PHY_ID   0x001378E0 +#define GG82563_E_PHY_ID   0x01410CA0  /* Miscellaneous PHY bit definitions. */  #define PHY_PREAMBLE			0xFFFFFFFF @@ -1791,4 +2442,142 @@ struct e1000_hw {  #define ADVERTISE_1000_FULL		0x0020  #define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F	/* Everything but 1000-Half */ +#define ICH_FLASH_GFPREG   0x0000 +#define ICH_FLASH_HSFSTS   0x0004 +#define ICH_FLASH_HSFCTL   0x0006 +#define ICH_FLASH_FADDR    0x0008 +#define ICH_FLASH_FDATA0   0x0010 +#define ICH_FLASH_FRACC    0x0050 +#define ICH_FLASH_FREG0    0x0054 +#define ICH_FLASH_FREG1    0x0058 +#define ICH_FLASH_FREG2    0x005C +#define ICH_FLASH_FREG3    0x0060 +#define ICH_FLASH_FPR0     0x0074 +#define ICH_FLASH_FPR1     0x0078 +#define ICH_FLASH_SSFSTS   0x0090 +#define ICH_FLASH_SSFCTL   0x0092 +#define ICH_FLASH_PREOP    0x0094 +#define ICH_FLASH_OPTYPE   0x0096 +#define ICH_FLASH_OPMENU   0x0098 + +#define ICH_FLASH_REG_MAPSIZE      0x00A0 +#define ICH_FLASH_SECTOR_SIZE      4096 +#define ICH_GFPREG_BASE_MASK       0x1FFF +#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF + +#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */ +#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ + +/* SPI EEPROM Status Register */ +#define EEPROM_STATUS_RDY_SPI  0x01 +#define EEPROM_STATUS_WEN_SPI  0x02 +#define EEPROM_STATUS_BP0_SPI  0x04 +#define EEPROM_STATUS_BP1_SPI  0x08 +#define EEPROM_STATUS_WPEN_SPI 0x80 + +/* SW Semaphore Register */ +#define E1000_SWSM_SMBI		0x00000001 /* Driver Semaphore bit */ +#define E1000_SWSM_SWESMBI	0x00000002 /* FW Semaphore bit */ +#define E1000_SWSM_WMNG		0x00000004 /* Wake MNG Clock */ +#define E1000_SWSM_DRV_LOAD	0x00000008 /* Driver Loaded Bit */ + +/* FW Semaphore Register */ +#define E1000_FWSM_MODE_MASK    0x0000000E /* FW mode */ +#define E1000_FWSM_MODE_SHIFT            1 +#define E1000_FWSM_FW_VALID     0x00008000 /* FW established a valid mode */ + +#define E1000_FWSM_RSPCIPHY        0x00000040 /* Reset PHY on PCI reset */ +#define E1000_FWSM_DISSW           0x10000000 /* FW disable SW Write Access */ +#define E1000_FWSM_SKUSEL_MASK     0x60000000 /* LAN SKU select */ +#define E1000_FWSM_SKUEL_SHIFT     29 +#define E1000_FWSM_SKUSEL_EMB      0x0 /* Embedded SKU */ +#define E1000_FWSM_SKUSEL_CONS     0x1 /* Consumer SKU */ +#define E1000_FWSM_SKUSEL_PERF_100 0x2 /* Perf & Corp 10/100 SKU */ +#define E1000_FWSM_SKUSEL_PERF_GBE 0x3 /* Perf & Copr GbE SKU */ + +#define E1000_GCR       0x05B00 /* PCI-Ex Control */ +#define E1000_GSCL_1    0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2    0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3    0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4    0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */ +#define E1000_SWSM      0x05B50 /* SW Semaphore */ +#define E1000_FWSM      0x05B54 /* FW Semaphore */ +#define E1000_FFLT_DBG  0x05F04 /* Debug Register */ +#define E1000_HICR      0x08F00 /* Host Inteface Control */ + +#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF +#define IGP_ACTIVITY_LED_ENABLE 0x0300 +#define IGP_LED3_MODE           0x07000000 + +/* Mask bit for PHY class in Word 7 of the EEPROM */ +#define EEPROM_PHY_CLASS_A   0x8000 +#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F  /* Everything but 1000-Half */ +#define AUTONEG_ADVERTISE_10_100_ALL    0x000F /* All 10/100 speeds*/ +#define AUTONEG_ADVERTISE_10_ALL        0x0003 /* 10Mbps Full & Half speeds*/ + +#define E1000_KUMCTRLSTA_MASK           0x0000FFFF +#define E1000_KUMCTRLSTA_OFFSET         0x001F0000 +#define E1000_KUMCTRLSTA_OFFSET_SHIFT   16 +#define E1000_KUMCTRLSTA_REN            0x00200000 + +#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL      0x00000000 +#define E1000_KUMCTRLSTA_OFFSET_CTRL           0x00000001 +#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL       0x00000002 +#define E1000_KUMCTRLSTA_OFFSET_DIAG           0x00000003 +#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS       0x00000004 +#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM      0x00000009 +#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL        0x00000010 +#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES     0x0000001E +#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES      0x0000001F + +/* FIFO Control */ +#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS   0x00000008 +#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS   0x00000800 + +/* In-Band Control */ +#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT    0x00000500 +#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING  0x00000010 + +/* Half-Duplex Control */ +#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004 +#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT  0x00000000 + +#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL       0x0000001E + +#define E1000_KUMCTRLSTA_DIAG_FELPBK           0x2000 +#define E1000_KUMCTRLSTA_DIAG_NELPBK           0x1000 + +#define E1000_KUMCTRLSTA_K0S_100_EN            0x2000 +#define E1000_KUMCTRLSTA_K0S_GBE_EN            0x1000 +#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK   0x0003 + +#define E1000_MNG_ICH_IAMT_MODE         0x2 +#define E1000_MNG_IAMT_MODE             0x3 +#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */ +#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */ +/* Number of milliseconds we wait for PHY configuration done after MAC reset */ +#define PHY_CFG_TIMEOUT             100 +#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009 +#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000   0x00000008 +#define E1000_TXDMAC_DPP 0x00000001 +#define AUTO_ALL_MODES	0 + +#ifndef E1000_MASTER_SLAVE +/* Switch to override PHY master/slave setting */ +#define E1000_MASTER_SLAVE	e1000_ms_hw_default +#endif +/* Extended Transmit Control */ +#define E1000_TCTL_EXT_BST_MASK  0x000003FF /* Backoff Slot Time */ +#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ + +#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX   0x00010000 + +#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL + +#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 +#define E1000_MC_TBL_SIZE_ICH8LAN  32 + +#define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers +							after IMS clear */  #endif	/* _E1000_HW_H_ */ diff --git a/include/net.h b/include/net.h index 4a03717ae..4873000c0 100644 --- a/include/net.h +++ b/include/net.h @@ -119,10 +119,10 @@ extern struct eth_device *eth_get_dev(void);	/* get the current device MAC */  extern struct eth_device *eth_get_dev_by_name(char *devname); /* get device */  extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */  extern int eth_get_dev_index (void);		/* get the device index */ -extern void eth_set_enetaddr(int num, char* a);	/* Set new MAC address */  extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr);  extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);  extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr); +extern int eth_getenv_enetaddr_by_index(int index, uchar *enetaddr);  extern int eth_init(bd_t *bis);			/* Initialize the device */  extern int eth_send(volatile void *packet, int length);	   /* Send a packet */ diff --git a/include/pci_ids.h b/include/pci_ids.h index 400c540cb..d783c5b1a 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -1834,6 +1834,28 @@  #define PCI_DEVICE_ID_INTEL_82562ET	0x1031 +#define PCI_DEVICE_ID_INTEL_82571EB_COPPER      0x105E +#define PCI_DEVICE_ID_INTEL_82571EB_FIBER       0x105F +#define PCI_DEVICE_ID_INTEL_82571EB_SERDES      0x1060 +#define PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER 0x10A4 +#define PCI_DEVICE_ID_INTEL_82571PT_QUAD_COPPER 0x10D5 +#define PCI_DEVICE_ID_INTEL_82571EB_QUAD_FIBER  0x10A5 +#define PCI_DEVICE_ID_INTEL_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC +#define PCI_DEVICE_ID_INTEL_82571EB_SERDES_DUAL 0x10D9 +#define PCI_DEVICE_ID_INTEL_82571EB_SERDES_QUAD 0x10DA +#define PCI_DEVICE_ID_INTEL_82572EI_COPPER      0x107D +#define PCI_DEVICE_ID_INTEL_82572EI_FIBER       0x107E +#define PCI_DEVICE_ID_INTEL_82572EI_SERDES      0x107F +#define PCI_DEVICE_ID_INTEL_82572EI             0x10B9 +#define PCI_DEVICE_ID_INTEL_82573E              0x108B +#define PCI_DEVICE_ID_INTEL_82573E_IAMT         0x108C +#define PCI_DEVICE_ID_INTEL_82573L              0x109A +#define PCI_DEVICE_ID_INTEL_82546GB_QUAD_COPPER_KSP3 0x10B5 +#define PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_DPT     0x1096 +#define PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_DPT     0x1098 +#define PCI_DEVICE_ID_INTEL_80003ES2LAN_COPPER_SPT     0x10BA +#define PCI_DEVICE_ID_INTEL_80003ES2LAN_SERDES_SPT     0x10BB +  #define PCI_DEVICE_ID_INTEL_82815_MC	0x1130  #define PCI_DEVICE_ID_INTEL_82559ER	0x1209 diff --git a/net/Makefile b/net/Makefile index 835a04af4..ff87d87e4 100644 --- a/net/Makefile +++ b/net/Makefile @@ -23,7 +23,7 @@  include $(TOPDIR)/config.mk -# CFLAGS += -DET_DEBUG -DDEBUG +# CFLAGS += -DDEBUG  LIB	= $(obj)libnet.a diff --git a/net/bootp.c b/net/bootp.c index d5f9c4be6..0799ae2b0 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -8,17 +8,6 @@   *	Copyright 2000-2004 Wolfgang Denk, wd@denx.de   */ -#if 0 -#define DEBUG		1	/* general debug */ -#define DEBUG_BOOTP_EXT 1	/* Debug received vendor fields */ -#endif - -#ifdef DEBUG_BOOTP_EXT -#define debug_ext(fmt,args...)	printf (fmt ,##args) -#else -#define debug_ext(fmt,args...) -#endif -  #include <common.h>  #include <command.h>  #include <net.h> @@ -107,7 +96,7 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)  		retval = -6;  	} -	debug ("Filtering pkt = %d\n", retval); +	debug("Filtering pkt = %d\n", retval);  	return retval;  } @@ -129,7 +118,7 @@ static void BootpCopyNetParams(Bootp_t *bp)  	if (strlen(bp->bp_file) > 0)  		copy_filename (BootFile, bp->bp_file, sizeof(BootFile)); -	debug ("Bootfile: %s\n", BootFile); +	debug("Bootfile: %s\n", BootFile);  	/* Propagate to environment:  	 * don't delete exising entry when BOOTP / DHCP reply does @@ -156,7 +145,7 @@ static void BootpVendorFieldProcess (u8 * ext)  {  	int size = *(ext + 1); -	debug_ext ("[BOOTP] Processing extension %d... (%d bytes)\n", *ext, +	debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,  		   *(ext + 1));  	NetBootFileSize = 0; @@ -255,7 +244,7 @@ static void BootpVendorProcess (u8 * ext, int size)  {  	u8 *end = ext + size; -	debug_ext ("[BOOTP] Checking extension (%d bytes)...\n", size); +	debug("[BOOTP] Checking extension (%d bytes)...\n", size);  	while ((ext < end) && (*ext != 0xff)) {  		if (*ext == 0) { @@ -269,34 +258,27 @@ static void BootpVendorProcess (u8 * ext, int size)  		}  	} -#ifdef DEBUG_BOOTP_EXT -	puts ("[BOOTP] Received fields: \n"); +	debug("[BOOTP] Received fields: \n");  	if (NetOurSubnetMask) -		printf ("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask); +		debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);  	if (NetOurGatewayIP) -		printf ("NetOurGatewayIP	: %pI4", &NetOurGatewayIP); +		debug("NetOurGatewayIP	: %pI4", &NetOurGatewayIP); -	if (NetBootFileSize) { -		printf ("NetBootFileSize : %d\n", NetBootFileSize); -	} +	if (NetBootFileSize) +		debug("NetBootFileSize : %d\n", NetBootFileSize); -	if (NetOurHostName[0]) { -		printf ("NetOurHostName  : %s\n", NetOurHostName); -	} +	if (NetOurHostName[0]) +		debug("NetOurHostName  : %s\n", NetOurHostName); -	if (NetOurRootPath[0]) { -		printf ("NetOurRootPath  : %s\n", NetOurRootPath); -	} +	if (NetOurRootPath[0]) +		debug("NetOurRootPath  : %s\n", NetOurRootPath); -	if (NetOurNISDomain[0]) { -		printf ("NetOurNISDomain : %s\n", NetOurNISDomain); -	} +	if (NetOurNISDomain[0]) +		debug("NetOurNISDomain : %s\n", NetOurNISDomain); -	if (NetBootFileSize) { -		printf ("NetBootFileSize: %d\n", NetBootFileSize); -	} -#endif /* DEBUG_BOOTP_EXT */ +	if (NetBootFileSize) +		debug("NetBootFileSize: %d\n", NetBootFileSize);  }  /*   *	Handle a BOOTP received packet. @@ -307,7 +289,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)  	Bootp_t *bp;  	char	*s; -	debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n", +	debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",  		src, dest, len, sizeof (Bootp_t));  	bp = (Bootp_t *)pkt; @@ -330,7 +312,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)  	NetSetTimeout(0, (thand_f *)0); -	debug ("Got good BOOTP\n"); +	debug("Got good BOOTP\n");  	if ((s = getenv("autoload")) != NULL) {  		if (*s == 'n') { @@ -579,14 +561,9 @@ BootpRequest (void)  		/* get our mac */  		eth_getenv_enetaddr("ethaddr", bi_enetaddr); -#ifdef DEBUG -		puts ("BootpRequest => Our Mac: "); -		for (reg=0; reg<6; reg++) { -			printf ("%x%c", -				bi_enetaddr[reg], -				reg==5 ? '\n' : ':'); -		} -#endif /* DEBUG */ +		debug("BootpRequest => Our Mac: "); +		for (reg=0; reg<6; reg++) +			debug("%x%c", bi_enetaddr[reg], reg==5 ? '\n' : ':');  		/* Mac-Manipulation 2 get seed1 */  		tst1=0; @@ -820,7 +797,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)  	int pktlen, iplen, extlen;  	IPaddr_t OfferedIP; -	debug ("DhcpSendRequestPkt: Sending DHCPREQUEST\n"); +	debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n");  	pkt = NetTxPacket;  	memset ((void*)pkt, 0, PKTSIZE); @@ -864,7 +841,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer)  	iplen = BOOTP_HDR_SIZE - sizeof(bp->bp_vend) + extlen;  	NetSetIP(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen); -	debug ("Transmitting DHCPREQUEST packet: len = %d\n", pktlen); +	debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);  #ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY  	udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);  #endif	/* CONFIG_BOOTP_DHCP_REQUEST_DELAY */ @@ -879,13 +856,13 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)  {  	Bootp_t *bp = (Bootp_t *)pkt; -	debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n", +	debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",  		src, dest, len, dhcp_state);  	if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */  		return; -	debug ("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n", +	debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",  		src, dest, len, dhcp_state);  	switch (dhcp_state) { @@ -896,14 +873,14 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)  		 * If filename is in format we recognize, assume it is a valid  		 * OFFER from a server we want.  		 */ -		debug ("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file); +		debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);  #ifdef CONFIG_SYS_BOOTFILE_PREFIX  		if (strncmp(bp->bp_file,  			    CONFIG_SYS_BOOTFILE_PREFIX,  			    strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0 ) {  #endif	/* CONFIG_SYS_BOOTFILE_PREFIX */ -			debug ("TRANSITIONING TO REQUESTING STATE\n"); +			debug("TRANSITIONING TO REQUESTING STATE\n");  			dhcp_state = REQUESTING;  			if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC)) @@ -918,7 +895,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)  		return;  		break;  	case REQUESTING: -		debug ("DHCP State: REQUESTING\n"); +		debug("DHCP State: REQUESTING\n");  		if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {  			char *s; @@ -53,6 +53,13 @@ int eth_setenv_enetaddr(char *name, const uchar *enetaddr)  	return setenv(name, buf);  } + +int eth_getenv_enetaddr_by_index(int index, uchar *enetaddr) +{ +	char enetvar[32]; +	sprintf(enetvar, index ? "eth%daddr" : "ethaddr", index); +	return eth_getenv_enetaddr(enetvar, enetaddr); +}  #endif  #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) @@ -180,7 +187,6 @@ int eth_register(struct eth_device* dev)  int eth_initialize(bd_t *bis)  { -	char enetvar[32];  	unsigned char env_enetaddr[6];  	int eth_number = 0; @@ -221,8 +227,7 @@ int eth_initialize(bd_t *bis)  				puts (" [PRIME]");  			} -			sprintf(enetvar, eth_number ? "eth%daddr" : "ethaddr", eth_number); -			eth_getenv_enetaddr(enetvar, env_enetaddr); +			eth_getenv_enetaddr_by_index(eth_number, env_enetaddr);  			if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {  				if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) && @@ -259,31 +264,6 @@ int eth_initialize(bd_t *bis)  	return eth_number;  } -void eth_set_enetaddr(int num, char *addr) { -	struct eth_device *dev; -	unsigned char enetaddr[6]; - -	debug ("eth_set_enetaddr(num=%d, addr=%s)\n", num, addr); - -	if (!eth_devices) -		return; - -	eth_parse_enetaddr(addr, enetaddr); - -	dev = eth_devices; -	while(num-- > 0) { -		dev = dev->next; - -		if (dev == eth_devices) -			return; -	} - -	debug ( "Setting new HW address on %s\n" -		"New Address is             %pM\n", -		dev->name, enetaddr); - -	memcpy(dev->enetaddr, enetaddr, 6); -}  #ifdef CONFIG_MCAST_TFTP  /* Multicast.   * mcast_addr: multicast ipaddr from which multicast Mac is made @@ -332,23 +312,37 @@ u32 ether_crc (size_t len, unsigned char const *p)  int eth_init(bd_t *bis)  { -	struct eth_device* old_current; +	int eth_number; +	struct eth_device *old_current, *dev;  	if (!eth_current) {  		puts ("No ethernet found.\n");  		return -1;  	} +	/* Sync environment with network devices */ +	eth_number = 0; +	dev = eth_devices; +	do { +		uchar env_enetaddr[6]; + +		if (eth_getenv_enetaddr_by_index(eth_number, env_enetaddr)) +			memcpy(dev->enetaddr, env_enetaddr, 6); + +		++eth_number; +		dev = dev->next; +	} while (dev != eth_devices); +  	old_current = eth_current;  	do { -		debug ("Trying %s\n", eth_current->name); +		debug("Trying %s\n", eth_current->name);  		if (eth_current->init(eth_current,bis) >= 0) {  			eth_current->state = ETH_STATE_ACTIVE;  			return 0;  		} -		debug  ("FAIL\n"); +		debug("FAIL\n");  		eth_try_another(0);  	} while (old_current != eth_current); @@ -113,10 +113,6 @@ DECLARE_GLOBAL_DATA_PTR;  # define ARP_TIMEOUT_COUNT	CONFIG_NET_RETRY_COUNT  #endif -#if 0 -#define ET_DEBUG -#endif -  /** BOOTP EXTENTIONS **/  IPaddr_t	NetOurSubnetMask=0;		/* Our subnet mask (0=unknown)	*/ @@ -218,9 +214,8 @@ void ArpRequest (void)  	volatile uchar *pkt;  	ARP_t *arp; -#ifdef ET_DEBUG -	printf ("ARP broadcast %d\n", NetArpWaitTry); -#endif +	debug("ARP broadcast %d\n", NetArpWaitTry); +  	pkt = NetTxPacket;  	pkt += NetSetEther (pkt, NetBcastAddr, PROT_ARP); @@ -644,9 +639,8 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)  	/* if MAC address was not discovered yet, save the packet and do an ARP request */  	if (memcmp(ether, NetEtherNullAddr, 6) == 0) { -#ifdef ET_DEBUG -		printf("sending ARP for %08lx\n", dest); -#endif +		debug("sending ARP for %08lx\n", dest); +  		NetArpWaitPacketIP = dest;  		NetArpWaitPacketMAC = ether; @@ -666,9 +660,7 @@ NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)  		return 1;	/* waiting */  	} -#ifdef ET_DEBUG -	printf("sending UDP to %08lx/%pM\n", dest, ether); -#endif +	debug("sending UDP to %08lx/%pM\n", dest, ether);  	pkt = (uchar *)NetTxPacket;  	pkt += NetSetEther (pkt, ether, PROT_IP); @@ -692,9 +684,7 @@ int PingSend(void)  	memcpy(mac, NetEtherNullAddr, 6); -#ifdef ET_DEBUG -	printf("sending ARP for %08lx\n", NetPingIP); -#endif +	debug("sending ARP for %08lx\n", NetPingIP);  	NetArpWaitPacketIP = NetPingIP;  	NetArpWaitPacketMAC = mac; @@ -1132,9 +1122,7 @@ NetReceive(volatile uchar * inpkt, int len)  #endif  	ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; -#ifdef ET_DEBUG -	printf("packet received\n"); -#endif +	debug("packet received\n");  	NetRxPacket = inpkt;  	NetRxPacketLen = len; @@ -1165,9 +1153,7 @@ NetReceive(volatile uchar * inpkt, int len)  	x = ntohs(et->et_protlen); -#ifdef ET_DEBUG -	printf("packet received\n"); -#endif +	debug("packet received\n");  	if (x < 1514) {  		/* @@ -1185,9 +1171,8 @@ NetReceive(volatile uchar * inpkt, int len)  	} else {			/* VLAN packet */  		VLAN_Ethernet_t *vet = (VLAN_Ethernet_t *)et; -#ifdef ET_DEBUG -		printf("VLAN packet received\n"); -#endif +		debug("VLAN packet received\n"); +  		/* too small packet? */  		if (len < VLAN_ETHER_HDR_SIZE)  			return; @@ -1208,9 +1193,7 @@ NetReceive(volatile uchar * inpkt, int len)  		len -= VLAN_ETHER_HDR_SIZE;  	} -#ifdef ET_DEBUG -	printf("Receive from protocol 0x%x\n", x); -#endif +	debug("Receive from protocol 0x%x\n", x);  #if defined(CONFIG_CMD_CDP)  	if (iscdp) { @@ -1239,9 +1222,8 @@ NetReceive(volatile uchar * inpkt, int len)  		 *   address; so if we receive such a packet, we set  		 *   the server ethernet address  		 */ -#ifdef ET_DEBUG -		puts ("Got ARP\n"); -#endif +		debug("Got ARP\n"); +  		arp = (ARP_t *)ip;  		if (len < ARP_HDR_SIZE) {  			printf("bad length %d < %d\n", len, ARP_HDR_SIZE); @@ -1270,9 +1252,7 @@ NetReceive(volatile uchar * inpkt, int len)  		switch (ntohs(arp->ar_op)) {  		case ARPOP_REQUEST:		/* reply with our IP address	*/ -#ifdef ET_DEBUG -			puts ("Got ARP REQUEST, return our IP\n"); -#endif +			debug("Got ARP REQUEST, return our IP\n");  			pkt = (uchar *)et;  			pkt += NetSetEther(pkt, et->et_src, PROT_ARP);  			arp->ar_op = htons(ARPOP_REPLY); @@ -1296,18 +1276,14 @@ NetReceive(volatile uchar * inpkt, int len)  			}  #endif -#ifdef ET_DEBUG -			printf("Got ARP REPLY, set server/gtwy eth addr (%pM)\n", +			debug("Got ARP REPLY, set server/gtwy eth addr (%pM)\n",  				arp->ar_data); -#endif  			tmp = NetReadIP(&arp->ar_data[6]);  			/* matched waiting packet's address */  			if (tmp == NetArpWaitReplyIP) { -#ifdef ET_DEBUG -				puts ("Got it\n"); -#endif +				debug("Got it\n");  				/* save address for later use */  				memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); @@ -1326,17 +1302,13 @@ NetReceive(volatile uchar * inpkt, int len)  			}  			return;  		default: -#ifdef ET_DEBUG -			printf("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op)); -#endif +			debug("Unexpected ARP opcode 0x%x\n", ntohs(arp->ar_op));  			return;  		}  		break;  	case PROT_RARP: -#ifdef ET_DEBUG -		puts ("Got RARP\n"); -#endif +		debug("Got RARP\n");  		arp = (ARP_t *)ip;  		if (len < ARP_HDR_SIZE) {  			printf("bad length %d < %d\n", len, ARP_HDR_SIZE); @@ -1360,11 +1332,9 @@ NetReceive(volatile uchar * inpkt, int len)  		break;  	case PROT_IP: -#ifdef ET_DEBUG -		puts ("Got IP\n"); -#endif +		debug("Got IP\n");  		if (len < IP_HDR_SIZE) { -			debug ("len bad %d < %lu\n", len, (ulong)IP_HDR_SIZE); +			debug("len bad %d < %lu\n", len, (ulong)IP_HDR_SIZE);  			return;  		}  		if (len < ntohs(ip->ip_len)) { @@ -1372,9 +1342,8 @@ NetReceive(volatile uchar * inpkt, int len)  			return;  		}  		len = ntohs(ip->ip_len); -#ifdef ET_DEBUG -		printf("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); -#endif +		debug("len=%d, v=%02x\n", len, ip->ip_hl_v & 0xff); +  		if ((ip->ip_hl_v & 0xf0) != 0x40) {  			return;  		} @@ -1432,10 +1401,9 @@ NetReceive(volatile uchar * inpkt, int len)  				(*packetHandler)((uchar *)ip, 0, 0, 0);  				return;  			case ICMP_ECHO_REQUEST: -#ifdef ET_DEBUG -				printf ("Got ICMP ECHO REQUEST, return %d bytes \n", +				debug("Got ICMP ECHO REQUEST, return %d bytes \n",  					ETHER_HDR_SIZE + len); -#endif +  				memcpy (&et->et_dest[0], &et->et_src[0], 6);  				memcpy (&et->et_src[ 0], NetOurEther, 6); @@ -29,8 +29,6 @@  #include "nfs.h"  #include "bootp.h" -/*#define NFS_DEBUG*/ -  #if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)  #define HASHES_PER_LINE 65	/* Number of "loading" hashes per line	*/ @@ -357,9 +355,7 @@ RPC request dispatcher  static void  NfsSend (void)  { -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	switch (NfsState) {  	case STATE_PRCLOOKUP_PROG_MOUNT_REQ: @@ -397,9 +393,7 @@ rpc_lookup_reply (int prog, uchar *pkt, unsigned len)  	memcpy ((unsigned char *)&rpc_pkt, pkt, len); -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	if (ntohl(rpc_pkt.u.reply.id) != rpc_id)  		return -1; @@ -427,9 +421,7 @@ nfs_mount_reply (uchar *pkt, unsigned len)  {  	struct rpc_t rpc_pkt; -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	memcpy ((unsigned char *)&rpc_pkt, pkt, len); @@ -454,9 +446,7 @@ nfs_umountall_reply (uchar *pkt, unsigned len)  {  	struct rpc_t rpc_pkt; -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	memcpy ((unsigned char *)&rpc_pkt, pkt, len); @@ -480,9 +470,7 @@ nfs_lookup_reply (uchar *pkt, unsigned len)  {  	struct rpc_t rpc_pkt; -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	memcpy ((unsigned char *)&rpc_pkt, pkt, len); @@ -507,9 +495,7 @@ nfs_readlink_reply (uchar *pkt, unsigned len)  	struct rpc_t rpc_pkt;  	int rlen; -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	memcpy ((unsigned char *)&rpc_pkt, pkt, len); @@ -544,9 +530,7 @@ nfs_read_reply (uchar *pkt, unsigned len)  	struct rpc_t rpc_pkt;  	int rlen; -#ifdef NFS_DEBUG_nop -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	memcpy ((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply)); @@ -601,9 +585,7 @@ NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)  {  	int rlen; -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	if (dest != NfsOurPort) return; @@ -661,9 +643,7 @@ NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)  			NfsState = STATE_UMOUNT_REQ;  			NfsSend ();  		} else { -#ifdef NFS_DEBUG -			printf ("Symlink --> %s\n", nfs_path); -#endif +			debug("Symlink --> %s\n", nfs_path);  			nfs_filename = basename (nfs_path);  			nfs_path     = dirname (nfs_path); @@ -696,9 +676,7 @@ NfsHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)  void  NfsStart (void)  { -#ifdef NFS_DEBUG -	printf ("%s\n", __FUNCTION__); -#endif +	debug("%s\n", __func__);  	NfsDownloadState = NETLOOP_FAIL;  	NfsServerIP = NetServerIP; diff --git a/net/rarp.c b/net/rarp.c index 710569626..d37981bfc 100644 --- a/net/rarp.c +++ b/net/rarp.c @@ -48,9 +48,7 @@ static void  RarpHandler(uchar * dummi0, unsigned dummi1, unsigned dummi2, unsigned dummi3)  {  	char *s; -#ifdef	DEBUG -	puts ("Got good RARP\n"); -#endif +	debug("Got good RARP\n");  	if ((s = getenv("autoload")) != NULL) {  		if (*s == 'n') {  			/* diff --git a/net/sntp.c b/net/sntp.c index 404587e80..76c10ecd3 100644 --- a/net/sntp.c +++ b/net/sntp.c @@ -23,7 +23,7 @@ SntpSend (void)  	int pktlen = SNTP_PACKET_LEN;  	int sport; -	debug ("%s\n", __FUNCTION__); +	debug("%s\n", __func__);  	memset (&pkt, 0, sizeof(pkt)); @@ -54,7 +54,7 @@ SntpHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)  	struct rtc_time tm;  	ulong seconds; -	debug ("%s\n", __FUNCTION__); +	debug("%s\n", __func__);  	if (dest != SntpOurPort) return; @@ -78,7 +78,7 @@ SntpHandler (uchar *pkt, unsigned dest, unsigned src, unsigned len)  void  SntpStart (void)  { -	debug ("%s\n", __FUNCTION__); +	debug("%s\n", __func__);  	NetSetTimeout (SNTP_TIMEOUT, SntpTimeout);  	NetSetHandler(SntpHandler); diff --git a/net/tftp.c b/net/tftp.c index b0f1cca0b..74d9e4215 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -10,8 +10,6 @@  #include "tftp.h"  #include "bootp.h" -#undef	ET_DEBUG -  #if defined(CONFIG_CMD_NET)  #define WELL_KNOWN_PORT	69		/* Well known TFTP port #		*/ @@ -196,9 +194,7 @@ TftpSend (void)  		strcpy ((char *)pkt, "timeout");  		pkt += 7 /*strlen("timeout")*/ + 1;  		sprintf((char *)pkt, "%lu", TIMEOUT / 1000); -#ifdef ET_DEBUG -		printf("send option \"timeout %s\"\n", (char *)pkt); -#endif +		debug("send option \"timeout %s\"\n", (char *)pkt);  		pkt += strlen((char *)pkt) + 1;  		/* try for more effic. blk size */  		pkt += sprintf((char *)pkt,"blksize%c%d%c", @@ -295,9 +291,7 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)  		break;  	case TFTP_OACK: -#ifdef ET_DEBUG -		printf("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1); -#endif +		debug("Got OACK: %s %s\n", pkt, pkt+strlen(pkt)+1);  		TftpState = STATE_OACK;  		TftpServerPort = src;  		/* @@ -309,10 +303,8 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)  			if (strcmp ((char*)pkt+i,"blksize") == 0) {  				TftpBlkSize = (unsigned short)  					simple_strtoul((char*)pkt+i+8,NULL,10); -#ifdef ET_DEBUG -				printf ("Blocksize ack: %s, %d\n", +				debug("Blocksize ack: %s, %d\n",  					(char*)pkt+i+8,TftpBlkSize); -#endif  				break;  			}  		} @@ -348,11 +340,8 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)  			}  		} -#ifdef ET_DEBUG -		if (TftpState == STATE_RRQ) { -			puts ("Server did not acknowledge timeout option!\n"); -		} -#endif +		if (TftpState == STATE_RRQ) +			debug("Server did not acknowledge timeout option!\n");  		if (TftpState == STATE_RRQ || TftpState == STATE_OACK) {  			/* first block received */ |