static void e1000_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; u32 *regs_buff = p; u16 phy_data; u8 revision_id; memset(p, 0, E1000_REGS_LEN * sizeof(u32)); pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; regs_buff[0] = er32(CTRL); regs_buff[1] = er32(STATUS); regs_buff[2] = er32(RCTL); regs_buff[3] = er32(RDLEN); regs_buff[4] = er32(RDH); regs_buff[5] = er32(RDT); regs_buff[6] = er32(RDTR); regs_buff[7] = er32(TCTL); regs_buff[8] = er32(TDLEN); regs_buff[9] = er32(TDH); regs_buff[10] = er32(TDT); regs_buff[11] = er32(TIDV); regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ /* ethtool doesn't use anything past this point, so all this * code is likely legacy junk for apps that may or may not * exist */ if (hw->phy.type == e1000_phy_m88) { e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); regs_buff[13] = (u32)phy_data; /* cable length */ regs_buff[14] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[15] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[16] = 0; /* Dummy (to align w/ IGP phy reg dump) */ e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); regs_buff[17] = (u32)phy_data; /* extended 10bt distance */ regs_buff[18] = regs_buff[13]; /* cable polarity */ regs_buff[19] = 0; /* Dummy (to align w/ IGP phy reg dump) */ regs_buff[20] = regs_buff[17]; /* polarity correction */ /* phy receive errors */ regs_buff[22] = adapter->phy_stats.receive_errors; regs_buff[23] = regs_buff[13]; /* mdix mode */ } regs_buff[21] = 0; /* was idle_errors */ e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); regs_buff[24] = (u32)phy_data; /* phy local receiver status */ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ }
/** * e1000e_reset - bring the hardware into a known good state * * This function boots the hardware and enables some settings that * require a configuration cycle of the hardware - those cannot be * set/changed during runtime. After reset the device needs to be * properly configured for Rx, Tx etc. */ void e1000e_reset(struct e1000_adapter *adapter) { struct e1000_mac_info *mac = &adapter->hw.mac; struct e1000_fc_info *fc = &adapter->hw.fc; u32 pba = adapter->pba; struct e1000_hw *hw = &adapter->hw; /* Reset Packet Buffer Allocation to default */ ew32(PBA, pba); hw->fc.requested_mode = e1000_fc_none; fc->current_mode = fc->requested_mode; /* Allow time for pending master requests to run */ mac->ops.reset_hw(hw); /* * For parts with AMT enabled, let the firmware know * that the network interface is in control */ if (adapter->flags & FLAG_HAS_AMT) e1000e_get_hw_control(adapter); ew32(WUC, 0); if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) e1e_wphy(&adapter->hw, BM_WUC, 0); if (mac->ops.init_hw(hw)) DBG("Hardware Error\n"); /* additional part of the flow-control workaround above */ if (hw->mac.type == e1000_pchlan) ew32(FCRTV_PCH, 0x1000); e1000e_reset_adaptive(hw); e1000e_get_phy_info(hw); if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && !(adapter->flags & FLAG_SMART_POWER_DOWN)) { u16 phy_data = 0; /* * speed up time to link by disabling smart power down, ignore * the return value of this function because there is nothing * different we would do if it failed */ e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); phy_data &= ~IGP02E1000_PM_SPD; e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); } }
void IntelMausi::intelSetupRxControl(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl, rfctl; /* Workaround Si errata on PCHx - configure jumbo frame flow. * If jumbo frames not set, program related MAC/PHY registers * to h/w defaults */ if (hw->mac.type >= e1000_pch2lan) { s32 ret_val; if (mtu > ETH_DATA_LEN) ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); else ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); if (ret_val) DebugLog("Ethernet [IntelMausi]: failed to enable/disable jumbo frame workaround mode.\n"); } /* Program MC offset vector base */ rctl = intelReadMem32(E1000_RCTL); rctl &= ~(3 << E1000_RCTL_MO_SHIFT); rctl |= E1000_RCTL_BAM | E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); /* Do not Store bad packets */ rctl &= ~E1000_RCTL_SBP; /* Enable Long Packet receive */ if (mtu <= ETH_DATA_LEN) rctl &= ~E1000_RCTL_LPE; else rctl |= E1000_RCTL_LPE; /* Some systems expect that the CRC is included in SMBUS traffic. The * hardware strips the CRC before sending to both SMBUS (BMC) and to * host memory when this is enabled */ if (adapter->flags2 & FLAG2_CRC_STRIPPING) rctl |= E1000_RCTL_SECRC; /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */ if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) { u16 phy_data; e1e_rphy(hw, PHY_REG(770, 26), &phy_data); phy_data &= 0xfff8; phy_data |= (1 << 2); e1e_wphy(hw, PHY_REG(770, 26), phy_data); e1e_rphy(hw, 22, &phy_data); phy_data &= 0x0fff; phy_data |= (1 << 14); e1e_wphy(hw, 0x10, 0x2823); e1e_wphy(hw, 0x11, 0x0003); e1e_wphy(hw, 22, phy_data); } /* Set buffer sizes to 2048 */ //rctl |= (0x2 << E1000_RCTL_FLXB_SHIFT); rctl &= ~(E1000_RCTL_SZ_256 | E1000_RCTL_BSEX); /* Enable Extended Status in all Receive Descriptors */ rfctl = intelReadMem32(E1000_RFCTL); rfctl |= (E1000_RFCTL_NEW_IPV6_EXT_DIS | E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_EXTEN | E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS); intelWriteMem32(E1000_RFCTL, rfctl); intelWriteMem32(E1000_RCTL, rctl); }
static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_reg = 0; u32 stat_reg = 0; u16 phy_reg = 0; hw->mac.autoneg = 0; if (hw->phy.type == e1000_phy_m88) { /* Auto-MDI/MDIX Off */ e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); /* reset to update Auto-MDI/MDIX */ e1e_wphy(hw, PHY_CONTROL, 0x9140); /* autoneg off */ e1e_wphy(hw, PHY_CONTROL, 0x8140); } else if (hw->phy.type == e1000_phy_gg82563) e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); ctrl_reg = er32(CTRL); switch (hw->phy.type) { case e1000_phy_ife: /* force 100, set loopback */ e1e_wphy(hw, PHY_CONTROL, 0x6100); /* Now set up the MAC to the same speed/duplex as the PHY. */ ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ E1000_CTRL_SPD_100 |/* Force Speed to 100 */ E1000_CTRL_FD); /* Force Duplex to FULL */ break; case e1000_phy_bm: /* Set Default MAC Interface speed to 1GB */ e1e_rphy(hw, PHY_REG(2, 21), &phy_reg); phy_reg &= ~0x0007; phy_reg |= 0x006; e1e_wphy(hw, PHY_REG(2, 21), phy_reg); /* Assert SW reset for above settings to take effect */ e1000e_commit_phy(hw); mdelay(1); /* Force Full Duplex */ e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C); /* Set Link Up (in force link) */ e1e_rphy(hw, PHY_REG(776, 16), &phy_reg); e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040); /* Force Link */ e1e_rphy(hw, PHY_REG(769, 16), &phy_reg); e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040); /* Set Early Link Enable */ e1e_rphy(hw, PHY_REG(769, 20), &phy_reg); e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400); /* fall through */ default: /* force 1000, set loopback */ e1e_wphy(hw, PHY_CONTROL, 0x4140); mdelay(250); /* Now set up the MAC to the same speed/duplex as the PHY. */ ctrl_reg = er32(CTRL); ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */ E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */ E1000_CTRL_FD); /* Force Duplex to FULL */ if (adapter->flags & FLAG_IS_ICH) ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ } if (hw->phy.media_type == e1000_media_type_copper && hw->phy.type == e1000_phy_m88) { ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ } else { /* * Set the ILOS bit on the fiber Nic if half duplex link is * detected. */ stat_reg = er32(STATUS); if ((stat_reg & E1000_STATUS_FD) == 0) ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); } ew32(CTRL, ctrl_reg); /* * Disable the receiver on the PHY so when a cable is plugged in, the * PHY does not begin to autoneg when a cable is reconnected to the NIC. */ if (hw->phy.type == e1000_phy_m88) e1000_phy_disable_receiver(adapter); udelay(500); return 0; }