e1000_hw.c

来自「linux 内核源代码」· C语言 代码 · 共 1,786 行 · 第 1/5 页

C
1,786
字号
	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;	}	switch (hw->mac_type) {	case e1000_ich8lan:		hw->swfwhw_semaphore_present = TRUE;		hw->asf_firmware_present = TRUE;		break;	case e1000_80003es2lan:		hw->swfw_sync_present = TRUE;		/* fall through */	case e1000_82571:	case e1000_82572:	case e1000_82573:		hw->eeprom_semaphore_present = TRUE;		/* fall through */	case e1000_82541:	case e1000_82547:	case e1000_82541_rev_2:	case e1000_82547_rev_2:		hw->asf_firmware_present = TRUE;		break;	default:		break;	}	/* The 82543 chip does not count tx_carrier_errors properly in	 * FD mode	 */	if (hw->mac_type == e1000_82543)		hw->bad_tx_carr_stats_fd = TRUE;	/* capable of receiving management packets to the host */	if (hw->mac_type >= e1000_82571)		hw->has_manc2h = TRUE;	/* In rare occasions, ESB2 systems would end up started without	 * the RX unit being turned on.	 */	if (hw->mac_type == e1000_80003es2lan)		hw->rx_needs_kicking = TRUE;	if (hw->mac_type > e1000_82544)		hw->has_smbus = TRUE;	return E1000_SUCCESS;}/***************************************************************************** * Set media type and TBI compatibility. * * hw - Struct containing variables accessed by shared code * **************************************************************************/voide1000_set_media_type(struct e1000_hw *hw){    uint32_t status;    DEBUGFUNC("e1000_set_media_type");    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;        }    }}/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code *****************************************************************************/int32_te1000_reset_hw(struct e1000_hw *hw){    uint32_t ctrl;    uint32_t ctrl_ext;    uint32_t icr;    uint32_t manc;    uint32_t led_ctrl;    uint32_t timeout;    uint32_t extcnf_ctrl;    int32_t ret_val;    DEBUGFUNC("e1000_reset_hw");    /* 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");        e1000_pci_clear_mwi(hw);    }    if (hw->bus_type == e1000_bus_type_pci_express) {        /* Prevent the PCI-E bus from sticking if there is no TLP connection         * on the last TLP read/write transaction when MAC is reset.         */        if (e1000_disable_pciex_master(hw) != E1000_SUCCESS) {            DEBUGOUT("PCI-E Master disable polling has failed.\n");        }    }    /* 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. */    hw->tbi_compatibility_on = FALSE;    /* Delay to allow any outstanding PCI transactions to complete before     * resetting the device     */    msleep(10);    ctrl = E1000_READ_REG(hw, CTRL);    /* Must reset the PHY before resetting the MAC */    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));        msleep(5);    }    /* Must acquire the MDIO ownership before MAC reset.     * Ownership defaults to firmware after a reset. */    if (hw->mac_type == e1000_82573) {        timeout = 10;        extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);        extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;        do {            E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);            extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);            if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)                break;            else                extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;            msleep(2);            timeout--;        } while (timeout);    }    /* Workaround for ICH8 bit corruption issue in FIFO memory */    if (hw->mac_type == e1000_ich8lan) {        /* Set Tx and Rx buffer allocation to 8k apiece. */        E1000_WRITE_REG(hw, PBA, E1000_PBA_8K);        /* Set Packet Buffer Size to 16k. */        E1000_WRITE_REG(hw, PBS, E1000_PBS_16K);    }    /* 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");    switch (hw->mac_type) {        case e1000_82544:        case e1000_82540:        case e1000_82545:        case e1000_82546:        case e1000_82541:        case e1000_82541_rev_2:            /* These controllers can't ack the 64-bit write when issuing the             * reset, so use IO-mapping as a workaround to issue the reset */            E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));            break;        case e1000_82545_rev_3:        case e1000_82546_rev_3:            /* Reset is performed on a shadow of the control register */            E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));            break;        case e1000_ich8lan:            if (!hw->phy_reset_disable &&                e1000_check_phy_reset_block(hw) == E1000_SUCCESS) {                /* e1000_ich8lan PHY HW reset requires MAC CORE reset                 * at the same time to make sure the interface between                 * MAC and the external PHY is reset.                 */                ctrl |= E1000_CTRL_PHY_RST;            }            e1000_get_software_flag(hw);            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));            msleep(5);            break;        default:            E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));            break;    }    /* After MAC reset, force reload of EEPROM to restore power-on settings to     * device.  Later controllers reload the EEPROM automatically, so just wait     * for reload to complete.     */    switch (hw->mac_type) {        case e1000_82542_rev2_0:        case e1000_82542_rev2_1:        case e1000_82543:        case e1000_82544:            /* 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 */            msleep(2);            break;        case e1000_82541:        case e1000_82541_rev_2:        case e1000_82547:        case e1000_82547_rev_2:            /* Wait for EEPROM reload */            msleep(20);            break;        case e1000_82573:            if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {                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);            }            /* fall through */        default:            /* Auto read done will delay 5ms or poll based on mac type */            ret_val = e1000_get_auto_rd_done(hw);            if (ret_val)                return ret_val;            break;    }    /* Disable HW ARPs on ASF enabled adapters */    if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {        manc = E1000_READ_REG(hw, MANC);        manc &= ~(E1000_MANC_ARP_EN);        E1000_WRITE_REG(hw, MANC, manc);    }    if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {        e1000_phy_init_script(hw);        /* 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);    }

⌨️ 快捷键说明

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