📄 e1000_hw.c
字号:
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;}/********************************************************************* Copper link setup for e1000_phy_igp series.** hw - Struct containing variables accessed by shared code*********************************************************************/static int32_te1000_copper_link_igp_setup(struct e1000_hw *hw){ uint32_t led_ctrl; int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_copper_link_igp_setup"); 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 */ msec_delay(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;}/********************************************************************* Copper link setup for e1000_phy_gg82563 series.** hw - Struct containing variables accessed by shared code*********************************************************************/static int32_te1000_copper_link_ggp_setup(struct e1000_hw *hw){ int32_t ret_val; uint16_t phy_data; uint32_t reg_data; DEBUGFUNC("e1000_copper_link_ggp_setup"); 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; if (hw->disable_polarity_correction == 1) 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_te1000_copper_link_mgp_setup(struct e1000_hw *hw){ int32_t ret_val; uint16_t phy_data; DEBUGFUNC("e1000_copper_link_mgp_setup"); 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; /* 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) */ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; switch (hw->mdix) { case 1: phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; break; case 2: phy_data |= M88E10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -