Skip to content
Snippets Groups Projects
e1000.c 155 KiB
Newer Older
  • Learn to ignore specific revisions
  • }
    
    /***************************************************************************
     *
     * 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)
    {
    
    #ifndef CONFIG_E1000_NO_NVM
    
    	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;
    }
    
    
    York Sun's avatar
    York Sun committed
    static bool e1000_is_second_port(struct e1000_hw *hw)
    
    {
    	switch (hw->mac_type) {
    	case e1000_80003es2lan:
    	case e1000_82546:
    	case e1000_82571:
    		if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
    
    York Sun's avatar
    York Sun committed
    			return true;
    
    York Sun's avatar
    York Sun committed
    		return false;
    
    #ifndef CONFIG_E1000_NO_NVM
    
    /******************************************************************************
     * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
     * second function of dual function devices
     *
     * nic - Struct containing variables accessed by shared code
     *****************************************************************************/
    static int
    e1000_read_mac_addr(struct eth_device *nic)
    {
    	struct e1000_hw *hw = nic->priv;
    	uint16_t offset;
    	uint16_t eeprom_data;
    	int i;
    
    	DEBUGFUNC();
    
    	for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
    		offset = i >> 1;
    		if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
    
    			DEBUGOUT("EEPROM Read Error\n");
    			return -E1000_ERR_EEPROM;
    		}
    		nic->enetaddr[i] = eeprom_data & 0xff;
    		nic->enetaddr[i + 1] = (eeprom_data >> 8) & 0xff;
    	}
    
    
    	/* Invert the last bit if this is the second device */
    	if (e1000_is_second_port(hw))
    		nic->enetaddr[5] ^= 1;
    
    
    Andre Schwarz's avatar
    Andre Schwarz committed
    #ifdef CONFIG_E1000_FALLBACK_MAC
    
    	if (!is_valid_ether_addr(nic->enetaddr)) {
    
    Stefan Roese's avatar
    Stefan Roese committed
    		unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC;
    
    		memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE);
    	}
    
    
    /******************************************************************************
     * Initializes receive address filters.
     *
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     * hw - Struct containing variables accessed by shared code
    
     *
     * Places the MAC address in receive address register 0 and clears the rest
     * of the receive addresss registers. Clears the multicast table. Assumes
     * the receiver is in reset when the routine is called.
     *****************************************************************************/
    static void
    e1000_init_rx_addrs(struct eth_device *nic)
    {
    	struct e1000_hw *hw = nic->priv;
    	uint32_t i;
    	uint32_t addr_low;
    	uint32_t addr_high;
    
    	DEBUGFUNC();
    
    	/* Setup the receive address. */
    	DEBUGOUT("Programming MAC Address into RAR[0]\n");
    	addr_low = (nic->enetaddr[0] |
    		    (nic->enetaddr[1] << 8) |
    		    (nic->enetaddr[2] << 16) | (nic->enetaddr[3] << 24));
    
    	addr_high = (nic->enetaddr[4] | (nic->enetaddr[5] << 8) | E1000_RAH_AV);
    
    	E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
    	E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
    
    	/* Zero out the other 15 receive addresses. */
    	DEBUGOUT("Clearing RAR[1-15]\n");
    	for (i = 1; i < E1000_RAR_ENTRIES; i++) {
    		E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
    		E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
    	}
    }
    
    /******************************************************************************
     * Clears the VLAN filer table
     *
     * hw - Struct containing variables accessed by shared code
     *****************************************************************************/
    static void
    e1000_clear_vfta(struct e1000_hw *hw)
    {
    	uint32_t offset;
    
    	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
    		E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
    }
    
    /******************************************************************************
     * Set the mac type member in the hw struct.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
    
     * hw - Struct containing variables accessed by shared code
     *****************************************************************************/
    
    int32_t
    
    e1000_set_mac_type(struct e1000_hw *hw)
    {
    	DEBUGFUNC();
    
    	switch (hw->device_id) {
    	case E1000_DEV_ID_82542:
    		switch (hw->revision_id) {
    		case E1000_82542_2_0_REV_ID:
    			hw->mac_type = e1000_82542_rev2_0;
    			break;
    		case E1000_82542_2_1_REV_ID:
    			hw->mac_type = e1000_82542_rev2_1;
    			break;
    		default:
    			/* Invalid 82542 revision ID */
    			return -E1000_ERR_MAC_TYPE;
    		}
    		break;
    	case E1000_DEV_ID_82543GC_FIBER:
    	case E1000_DEV_ID_82543GC_COPPER:
    		hw->mac_type = e1000_82543;
    		break;
    	case E1000_DEV_ID_82544EI_COPPER:
    	case E1000_DEV_ID_82544EI_FIBER:
    	case E1000_DEV_ID_82544GC_COPPER:
    	case E1000_DEV_ID_82544GC_LOM:
    		hw->mac_type = e1000_82544;
    		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_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;
    
    Andre Schwarz's avatar
    Andre Schwarz committed
    	case E1000_DEV_ID_82541ER:
    
    	case E1000_DEV_ID_82541GI:
    
    	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_82574L:
    		hw->mac_type = e1000_82574;
    		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;
    	}
    	return E1000_SUCCESS;
    }
    
    /******************************************************************************
     * Reset the transmit and receive units; mask and clear all interrupts.
     *
     * hw - Struct containing variables accessed by shared code
     *****************************************************************************/
    void
    e1000_reset_hw(struct e1000_hw *hw)
    {
    	uint32_t ctrl;
    	uint32_t ctrl_ext;
    	uint32_t manc;
    
    	/* get the correct pba value for both PCI and PCIe*/
    	if (hw->mac_type <  e1000_82571)
    		pba = E1000_DEFAULT_PCI_PBA;
    	else
    		pba = E1000_DEFAULT_PCIE_PBA;
    
    
    	/* For 82542 (rev 2.0), disable MWI before issuing a device reset */
    	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);
    
    	}
    
    	/* Clear interrupt mask to stop board from generating interrupts */
    	DEBUGOUT("Masking off all interrupts\n");
    	E1000_WRITE_REG(hw, IMC, 0xffffffff);
    
    	/* Disable the Transmit and Receive units.  Then delay to allow
    	 * any pending transactions to complete before we hit the MAC with
    	 * the global reset.
    	 */
    	E1000_WRITE_REG(hw, RCTL, 0);
    	E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
    	E1000_WRITE_FLUSH(hw);
    
    	/* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
    
    York Sun's avatar
    York Sun committed
    	hw->tbi_compatibility_on = false;
    
    
    	/* Delay to allow any outstanding PCI transactions to complete before
    	 * resetting the device
    	 */
    	mdelay(10);
    
    	/* Issue a global reset to the MAC.  This will reset the chip's
    	 * transmit, receive, DMA, and link units.  It will not effect
    	 * the current PCI configuration.  The global reset bit is self-
    	 * clearing, and should clear within a microsecond.
    	 */
    	DEBUGOUT("Issuing a global reset to MAC\n");
    	ctrl = E1000_READ_REG(hw, CTRL);
    
    
    	E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
    
    
    	/* Force a reload from the EEPROM if necessary */
    	if (hw->mac_type < e1000_82540) {
    		/* Wait for reset to complete */
    		udelay(10);
    		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
    		ctrl_ext |= E1000_CTRL_EXT_EE_RST;
    		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
    		E1000_WRITE_FLUSH(hw);
    		/* Wait for EEPROM reload */
    		mdelay(2);
    	} else {
    		/* Wait for EEPROM reload (it happens automatically) */
    		mdelay(4);
    		/* Dissable HW ARPs on ASF enabled adapters */
    		manc = E1000_READ_REG(hw, MANC);
    		manc &= ~(E1000_MANC_ARP_EN);
    		E1000_WRITE_REG(hw, MANC, manc);
    	}
    
    	/* Clear interrupt mask to stop board from generating interrupts */
    	DEBUGOUT("Masking off all interrupts\n");
    	E1000_WRITE_REG(hw, IMC, 0xffffffff);
    
    	/* Clear any pending interrupt events. */
    
    	E1000_READ_REG(hw, ICR);
    
    
    	/* If MWI was previously enabled, reenable it. */
    	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, 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:
    
    		case e1000_82574:
    
    			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);
    	}
    
    }
    
    /******************************************************************************
     * Performs basic configuration of the adapter.
     *
     * hw - Struct containing variables accessed by shared code
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
     * Assumes that the controller has previously been reset and is in a
    
     * post-reset uninitialized state. Initializes the receive address registers,
     * multicast table, and VLAN filter table. Calls routines to setup link
     * configuration and flow control settings. Clears all on-chip counters. Leaves
     * the transmit and receive units disabled and uninitialized.
     *****************************************************************************/
    static int
    e1000_init_hw(struct eth_device *nic)
    {
    	struct e1000_hw *hw = nic->priv;
    
    	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;
    
    	uint32_t mta_size;
    	uint32_t reg_data;
    	uint32_t ctrl_ext;
    
    	/* 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 */
    
    	/* 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");
    
    	/* 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) {
    		DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
    		pci_write_config_word(hw->pdev, PCI_COMMAND,
    				      hw->
    				      pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
    		E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
    		E1000_WRITE_FLUSH(hw);
    		mdelay(5);
    	}
    
    	/* Setup the receive address. This involves initializing all of the Receive
    	 * Address Registers (RARs 0 - 15).
    	 */
    	e1000_init_rx_addrs(nic);
    
    	/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
    	if (hw->mac_type == e1000_82542_rev2_0) {
    		E1000_WRITE_REG(hw, RCTL, 0);
    		E1000_WRITE_FLUSH(hw);
    		mdelay(1);
    		pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
    	}
    
    	/* Zero out the Multicast HASH table */
    	DEBUGOUT("Zeroing the MTA\n");
    
    	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.  Valid only on
    	 * 82542 and 82543 silicon.
    
    	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
    
    	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 (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,
    				     &pcix_stat_hi_word);
    		cmd_mmrbc =
    		    (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
    		    PCIX_COMMAND_MMRBC_SHIFT;
    		stat_mmrbc =
    		    (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
    		    PCIX_STATUS_HI_MMRBC_SHIFT;
    		if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
    			stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
    		if (cmd_mmrbc > stat_mmrbc) {
    			pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
    			pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
    			pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER,
    					      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);
    
    	/* Set the transmit descriptor write-back policy */
    	if (hw->mac_type > e1000_82544) {
    		ctrl = E1000_READ_REG(hw, TXDCTL);
    		ctrl =
    		    (ctrl & ~E1000_TXDCTL_WTHRESH) |
    		    E1000_TXDCTL_FULL_TX_DESC_WB;
    		E1000_WRITE_REG(hw, TXDCTL, ctrl);
    	}
    
    	/* Set the receive descriptor write back policy */
    
    	if (hw->mac_type >= e1000_82571) {
    		ctrl = E1000_READ_REG(hw, RXDCTL);
    		ctrl =
    		    (ctrl & ~E1000_RXDCTL_WTHRESH) |
    		    E1000_RXDCTL_FULL_RX_DESC_WB;
    		E1000_WRITE_REG(hw, RXDCTL, 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;
    
    	case e1000_82573:
    	case e1000_82574:
    		reg_data = E1000_READ_REG(hw, GCR);
    		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
    		E1000_WRITE_REG(hw, GCR, reg_data);
    
    #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
    	 * because the symbol error count will increment wildly if there
    	 * 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);
    
    	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;
    }
    
    /******************************************************************************
     * Configures flow control and link settings.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
    
     * hw - Struct containing variables accessed by shared code
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
    
     * Determines which flow control settings to use. Calls the apropriate media-
     * specific link configuration function. Configures the flow control settings.
     * Assuming the adapter has a valid link partner, a valid link should be
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     * established. Assumes the hardware has previously been reset and the
    
     * transmitter and receiver are not enabled.
     *****************************************************************************/
    static int
    e1000_setup_link(struct eth_device *nic)
    {
    	struct e1000_hw *hw = nic->priv;
    	int32_t ret_val;
    
    #ifndef CONFIG_E1000_NO_NVM
    	uint32_t ctrl_ext;
    
    	uint16_t eeprom_data;
    
    	/* 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_E1000_NO_NVM
    
    	/* Read and store word 0x0F of the EEPROM. This word contains bits
    	 * that determine the hardware's default PAUSE (flow control) mode,
    	 * a bit that determines whether the HW defaults to enabling or
    	 * disabling auto-negotiation, and the direction of the
    	 * SW defined pins. If there is no SW over-ride of the flow
    	 * 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, 1,
    				&eeprom_data) < 0) {
    
    		DEBUGOUT("EEPROM Read Error\n");
    		return -E1000_ERR_EEPROM;
    	}
    
    	if (hw->fc == e1000_fc_default) {
    
    		switch (hw->mac_type) {
    		case e1000_ich8lan:
    		case e1000_82573:
    
    		case e1000_82574:
    
    			hw->fc = e1000_fc_full;
    
    			break;
    		default:
    
    #ifndef CONFIG_E1000_NO_NVM
    
    			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;
    			}
    			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
    	 * in case we get disconnected and then reconnected into a different
    	 * hub or switch with different Flow Control capabilities.
    	 */
    	if (hw->mac_type == e1000_82542_rev2_0)
    		hw->fc &= (~e1000_fc_tx_pause);
    
    	if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
    		hw->fc &= (~e1000_fc_rx_pause);
    
    	hw->original_fc = hw->fc;
    
    	DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc);
    
    
    #ifndef CONFIG_E1000_NO_NVM
    
    	/* Take the 4 bits from EEPROM word 0x0F that determine the initial
    	 * polarity value for the SW controlled pins, and setup the
    	 * Extended Device Control reg with that info.
    	 * This is needed because one of the SW controlled pins is used for
    	 * signal detection.  So this should be done before e1000_setup_pcs_link()
    	 * or e1000_phy_setup() is called.
    	 */
    	if (hw->mac_type == e1000_82543) {
    		ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
    			    SWDPIO__EXT_SHIFT);
    		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
    	}
    
    
    	/* Call the necessary subroutine to configure the link. */
    	ret_val = (hw->media_type == e1000_media_type_fiber) ?
    	    e1000_setup_fiber_link(nic) : e1000_setup_copper_link(nic);
    	if (ret_val < 0) {
    		return ret_val;
    	}
    
    	/* Initialize the flow control address, type, and PAUSE timer
    	 * registers to their default values.  This is done even if flow
    	 * control is disabled, because it does not hurt anything to
    	 * initialize these registers.
    	 */
    
    	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, FCTTV, hw->fc_pause_time);
    
    	/* Set the flow control receive threshold registers.  Normally,
    	 * these registers will be set to a default threshold that may be
    	 * adjusted later by the driver's runtime code.  However, if the
    	 * ability to transmit pause frames in not enabled, then these
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	 * registers will be set to 0.
    
    	 */
    	if (!(hw->fc & e1000_fc_tx_pause)) {
    		E1000_WRITE_REG(hw, FCRTL, 0);
    		E1000_WRITE_REG(hw, FCRTH, 0);
    	} else {
    		/* We need to set up the Receive Threshold high and low water marks
    		 * as well as (optionally) enabling the transmission of XON frames.
    		 */
    		if (hw->fc_send_xon) {
    			E1000_WRITE_REG(hw, FCRTL,
    					(hw->fc_low_water | E1000_FCRTL_XONE));
    			E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
    		} else {
    			E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
    			E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
    		}
    	}
    	return ret_val;
    }
    
    /******************************************************************************
     * Sets up link for a fiber based adapter
     *
     * hw - Struct containing variables accessed by shared code
     *
     * Manipulates Physical Coding Sublayer functions in order to configure
     * link. Assumes the hardware has been previously reset and the transmitter
     * and receiver are not enabled.
     *****************************************************************************/
    static int
    e1000_setup_fiber_link(struct eth_device *nic)
    {
    	struct e1000_hw *hw = nic->priv;
    	uint32_t ctrl;
    	uint32_t status;
    	uint32_t txcw = 0;
    	uint32_t i;
    	uint32_t signal;
    	int32_t ret_val;
    
    	DEBUGFUNC();
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* On adapters with a MAC newer that 82544, SW Defineable pin 1 will be
    	 * set when the optics detect a signal. On older adapters, it will be
    
    	 * cleared when there is a signal
    	 */
    	ctrl = E1000_READ_REG(hw, CTRL);
    	if ((hw->mac_type > e1000_82544) && !(ctrl & E1000_CTRL_ILOS))
    		signal = E1000_CTRL_SWDPIN1;
    	else
    		signal = 0;
    
    	printf("signal for %s is %x (ctrl %08x)!!!!\n", nic->name, signal,
    	       ctrl);
    	/* Take the link out of reset */
    	ctrl &= ~(E1000_CTRL_LRST);
    
    	e1000_config_collision_dist(hw);
    
    	/* Check for a software override of the flow control settings, and setup
    	 * the device accordingly.  If auto-negotiation is enabled, then software
    	 * will have to set the "PAUSE" bits to the correct value in the Tranmsit
    	 * Config Word Register (TXCW) and re-start auto-negotiation.  However, if
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	 * auto-negotiation is disabled, then software will have to manually
    
    	 * configure the two flow control enable bits in the CTRL register.
    	 *
    	 * The possible values of the "fc" parameter are:
    
    	 *	0:  Flow control is completely disabled
    	 *	1:  Rx flow control is enabled (we can receive pause frames, but
    	 *	    not send pause frames).
    	 *	2:  Tx flow control is enabled (we can send pause frames but we do
    	 *	    not support receiving pause frames).
    	 *	3:  Both Rx and TX flow control (symmetric) are enabled.
    
    	 */
    	switch (hw->fc) {
    	case e1000_fc_none:
    		/* Flow control is completely disabled by a software over-ride. */
    		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
    		break;
    	case e1000_fc_rx_pause:
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		/* RX Flow control is enabled and TX Flow control is disabled by a
    		 * software over-ride. Since there really isn't a way to advertise
    
    		 * that we are capable of RX Pause ONLY, we will advertise that we
    		 * support both symmetric and asymmetric RX PAUSE. Later, we will
    		 *  disable the adapter's ability to send PAUSE frames.
    		 */
    		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
    		break;
    	case e1000_fc_tx_pause:
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		/* TX Flow control is enabled, and RX Flow control is disabled, by a
    
    		 * software over-ride.
    		 */
    		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
    		break;
    	case e1000_fc_full:
    		/* Flow control (both RX and TX) is enabled by a software over-ride. */
    		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
    		break;
    	default:
    		DEBUGOUT("Flow control param set incorrectly\n");
    		return -E1000_ERR_CONFIG;
    		break;
    	}
    
    	/* Since auto-negotiation is enabled, take the link out of reset (the link
    	 * will be in reset, because we previously reset the chip). This will
    	 * restart auto-negotiation.  If auto-neogtiation is successful then the
    	 * link-up status bit will be set and the flow control enable bits (RFCE
    	 * and TFCE) will be set according to their negotiated value.
    	 */
    	DEBUGOUT("Auto-negotiation enabled (%#x)\n", txcw);