e1000e: initial support for 82579 LOMs
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
eb7700dc03
commit
d3738bb820
|
@ -359,6 +359,7 @@
|
|||
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
|
||||
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
|
||||
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
|
||||
#define E1000_EXTCNF_CTRL_GATE_PHY_CFG 0x00000080
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
|
||||
#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000
|
||||
|
@ -714,6 +715,7 @@
|
|||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
#define I82579_E_PHY_ID 0x01540090
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
|
|
|
@ -164,6 +164,7 @@ enum e1000_boards {
|
|||
board_ich9lan,
|
||||
board_ich10lan,
|
||||
board_pchlan,
|
||||
board_pch2lan,
|
||||
};
|
||||
|
||||
struct e1000_queue_stats {
|
||||
|
@ -477,6 +478,7 @@ extern struct e1000_info e1000_ich8_info;
|
|||
extern struct e1000_info e1000_ich9_info;
|
||||
extern struct e1000_info e1000_ich10_info;
|
||||
extern struct e1000_info e1000_pch_info;
|
||||
extern struct e1000_info e1000_pch2_info;
|
||||
extern struct e1000_info e1000_es2_info;
|
||||
|
||||
extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
|
||||
|
@ -495,6 +497,8 @@ extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
|||
extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
|
||||
extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
|
||||
extern s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
|
||||
extern s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
|
||||
extern void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
|
||||
|
||||
extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
|
||||
extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
|
||||
|
|
|
@ -880,6 +880,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
|
|||
switch (mac->type) {
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
mask |= (1 << 18);
|
||||
break;
|
||||
default:
|
||||
|
@ -1321,6 +1322,17 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
|
|||
/* Workaround: K1 must be disabled for stable 1Gbps operation */
|
||||
e1000_configure_k1_ich8lan(hw, false);
|
||||
break;
|
||||
case e1000_phy_82579:
|
||||
/* Disable PHY energy detect power down */
|
||||
e1e_rphy(hw, PHY_REG(0, 21), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(0, 21), phy_reg & ~(1 << 3));
|
||||
/* Disable full chip energy detect */
|
||||
e1e_rphy(hw, PHY_REG(776, 18), &phy_reg);
|
||||
e1e_wphy(hw, PHY_REG(776, 18), phy_reg | 1);
|
||||
/* Enable loopback on the PHY */
|
||||
#define I82577_PHY_LBK_CTRL 19
|
||||
e1e_wphy(hw, I82577_PHY_LBK_CTRL, 0x8001);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1878,6 +1890,7 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
|
|||
|
||||
if ((hw->phy.type == e1000_phy_ife) ||
|
||||
(hw->mac.type == e1000_pchlan) ||
|
||||
(hw->mac.type == e1000_pch2lan) ||
|
||||
(hw->mac.type == e1000_82583) ||
|
||||
(hw->mac.type == e1000_82574)) {
|
||||
INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
|
||||
|
|
|
@ -217,7 +217,10 @@ enum e1e_registers {
|
|||
E1000_SWSM = 0x05B50, /* SW Semaphore */
|
||||
E1000_FWSM = 0x05B54, /* FW Semaphore */
|
||||
E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
|
||||
E1000_CRC_OFFSET = 0x05F50, /* CRC Offset register */
|
||||
E1000_FFLT_DBG = 0x05F04, /* Debug Register */
|
||||
E1000_PCH_RAICC_BASE = 0x05F50, /* Receive Address Initial CRC */
|
||||
#define E1000_PCH_RAICC(_n) (E1000_PCH_RAICC_BASE + ((_n) * 4))
|
||||
#define E1000_CRC_OFFSET E1000_PCH_RAICC_BASE
|
||||
E1000_HICR = 0x08F00, /* Host Interface Control */
|
||||
};
|
||||
|
||||
|
@ -303,13 +306,14 @@ enum e1e_registers {
|
|||
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
|
||||
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
|
||||
#define E1000_KMRNCTRLSTA_REN 0x00200000
|
||||
#define E1000_KMRNCTRLSTA_CTRL_OFFSET 0x1 /* Kumeran Control */
|
||||
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
|
||||
#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
|
||||
#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
|
||||
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
|
||||
#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
|
||||
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x140E
|
||||
#define E1000_KMRNCTRLSTA_K1_DISABLE 0x1400
|
||||
#define E1000_KMRNCTRLSTA_HD_CTRL 0x0002
|
||||
|
||||
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
|
||||
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
|
||||
|
@ -387,6 +391,8 @@ enum e1e_registers {
|
|||
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
|
||||
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
|
||||
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
|
||||
#define E1000_DEV_ID_PCH2_LV_LM 0x1502
|
||||
#define E1000_DEV_ID_PCH2_LV_V 0x1503
|
||||
|
||||
#define E1000_REVISION_4 4
|
||||
|
||||
|
@ -406,6 +412,7 @@ enum e1000_mac_type {
|
|||
e1000_ich9lan,
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
e1000_pch2lan,
|
||||
};
|
||||
|
||||
enum e1000_media_type {
|
||||
|
@ -442,6 +449,7 @@ enum e1000_phy_type {
|
|||
e1000_phy_bm,
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
e1000_phy_82579,
|
||||
};
|
||||
|
||||
enum e1000_bus_width {
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
* 82577LC Gigabit Network Connection
|
||||
* 82578DM Gigabit Network Connection
|
||||
* 82578DC Gigabit Network Connection
|
||||
* 82579LM Gigabit Network Connection
|
||||
* 82579V Gigabit Network Connection
|
||||
*/
|
||||
|
||||
#include "e1000.h"
|
||||
|
@ -126,6 +128,9 @@
|
|||
#define HV_SMB_ADDR_PEC_EN 0x0200
|
||||
#define HV_SMB_ADDR_VALID 0x0080
|
||||
|
||||
/* PHY Power Management Control */
|
||||
#define HV_PM_CTRL PHY_REG(770, 17)
|
||||
|
||||
/* Strapping Option Register - RO */
|
||||
#define E1000_STRAP 0x0000C
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
|
||||
|
@ -279,13 +284,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
|||
phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
|
||||
/*
|
||||
* The MAC-PHY interconnect may still be in SMBus mode
|
||||
* after Sx->S0. If the manageability engine (ME) is
|
||||
* disabled, then toggle the LANPHYPC Value bit to force
|
||||
* the interconnect to PCIe mode.
|
||||
*/
|
||||
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
|
||||
/*
|
||||
* The MAC-PHY interconnect may still be in SMBus mode
|
||||
* after Sx->S0. Toggle the LANPHYPC Value bit to force
|
||||
* the interconnect to PCIe mode, but only if there is no
|
||||
* firmware present otherwise firmware will have done it.
|
||||
*/
|
||||
ctrl = er32(CTRL);
|
||||
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
|
||||
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
|
||||
|
@ -326,6 +331,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
|||
|
||||
switch (phy->type) {
|
||||
case e1000_phy_82577:
|
||||
case e1000_phy_82579:
|
||||
phy->ops.check_polarity = e1000_check_polarity_82577;
|
||||
phy->ops.force_speed_duplex =
|
||||
e1000_phy_force_speed_duplex_82577;
|
||||
|
@ -530,6 +536,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
|
|||
mac->ops.led_off = e1000_led_off_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
/* check management mode */
|
||||
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
|
||||
/* ID LED init */
|
||||
|
@ -550,6 +557,14 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
|
|||
if (mac->type == e1000_ich8lan)
|
||||
e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
|
||||
|
||||
/* Disable PHY configuration by hardware, config by software */
|
||||
if (mac->type == e1000_pch2lan) {
|
||||
u32 extcnf_ctrl = er32(EXTCNF_CTRL);
|
||||
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
|
||||
ew32(EXTCNF_CTRL, extcnf_ctrl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -653,10 +668,19 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
|
|||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
rc = e1000_init_phy_params_pchlan(hw);
|
||||
else
|
||||
switch (hw->mac.type) {
|
||||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
rc = e1000_init_phy_params_ich8lan(hw);
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
rc = e1000_init_phy_params_pchlan(hw);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -861,6 +885,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
}
|
||||
/* Fall-thru */
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
break;
|
||||
default:
|
||||
|
@ -880,8 +905,10 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto out;
|
||||
if (!(hw->mac.type == e1000_pch2lan)) {
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto out;
|
||||
}
|
||||
|
||||
cnf_size = er32(EXTCNF_SIZE);
|
||||
cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
|
||||
|
@ -893,7 +920,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
|||
cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
|
||||
|
||||
if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
|
||||
(hw->mac.type == e1000_pchlan)) {
|
||||
((hw->mac.type == e1000_pchlan) ||
|
||||
(hw->mac.type == e1000_pch2lan))) {
|
||||
/*
|
||||
* HW configures the SMBus address and LEDs when the
|
||||
* OEM and LCD Write Enable bits are set in the NVM.
|
||||
|
@ -1100,16 +1128,18 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
|
|||
u32 mac_reg;
|
||||
u16 oem_reg;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
if ((hw->mac.type != e1000_pch2lan) && (hw->mac.type != e1000_pchlan))
|
||||
return ret_val;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto out;
|
||||
if (!(hw->mac.type == e1000_pch2lan)) {
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto out;
|
||||
}
|
||||
|
||||
mac_reg = er32(FEXTNVM);
|
||||
if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
|
||||
|
@ -1249,6 +1279,243 @@ out:
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_copy_rx_addrs_to_phy_ich8lan - Copy Rx addresses from MAC to PHY
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
u32 mac_reg;
|
||||
u16 i;
|
||||
|
||||
/* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */
|
||||
for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
|
||||
mac_reg = er32(RAL(i));
|
||||
e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
mac_reg = er32(RAH(i));
|
||||
e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0x8000));
|
||||
}
|
||||
}
|
||||
|
||||
static u32 e1000_calc_rx_da_crc(u8 mac[])
|
||||
{
|
||||
u32 poly = 0xEDB88320; /* Polynomial for 802.3 CRC calculation */
|
||||
u32 i, j, mask, crc;
|
||||
|
||||
crc = 0xffffffff;
|
||||
for (i = 0; i < 6; i++) {
|
||||
crc = crc ^ mac[i];
|
||||
for (j = 8; j > 0; j--) {
|
||||
mask = (crc & 1) * (-1);
|
||||
crc = (crc >> 1) ^ (poly & mask);
|
||||
}
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_lv_jumbo_workaround_ich8lan - required for jumbo frame operation
|
||||
* with 82579 PHY
|
||||
* @hw: pointer to the HW structure
|
||||
* @enable: flag to enable/disable workaround when enabling/disabling jumbos
|
||||
**/
|
||||
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u16 phy_reg, data;
|
||||
u32 mac_reg;
|
||||
u16 i;
|
||||
|
||||
if (hw->mac.type != e1000_pch2lan)
|
||||
goto out;
|
||||
|
||||
/* disable Rx path while enabling/disabling workaround */
|
||||
e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg | (1 << 14));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* Write Rx addresses (rar_entry_count for RAL/H, +4 for
|
||||
* SHRAL/H) and initial CRC values to the MAC
|
||||
*/
|
||||
for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
|
||||
u8 mac_addr[ETH_ALEN] = {0};
|
||||
u32 addr_high, addr_low;
|
||||
|
||||
addr_high = er32(RAH(i));
|
||||
if (!(addr_high & E1000_RAH_AV))
|
||||
continue;
|
||||
addr_low = er32(RAL(i));
|
||||
mac_addr[0] = (addr_low & 0xFF);
|
||||
mac_addr[1] = ((addr_low >> 8) & 0xFF);
|
||||
mac_addr[2] = ((addr_low >> 16) & 0xFF);
|
||||
mac_addr[3] = ((addr_low >> 24) & 0xFF);
|
||||
mac_addr[4] = (addr_high & 0xFF);
|
||||
mac_addr[5] = ((addr_high >> 8) & 0xFF);
|
||||
|
||||
ew32(PCH_RAICC(i),
|
||||
e1000_calc_rx_da_crc(mac_addr));
|
||||
}
|
||||
|
||||
/* Write Rx addresses to the PHY */
|
||||
e1000_copy_rx_addrs_to_phy_ich8lan(hw);
|
||||
|
||||
/* Enable jumbo frame workaround in the MAC */
|
||||
mac_reg = er32(FFLT_DBG);
|
||||
mac_reg &= ~(1 << 14);
|
||||
mac_reg |= (7 << 15);
|
||||
ew32(FFLT_DBG, mac_reg);
|
||||
|
||||
mac_reg = er32(RCTL);
|
||||
mac_reg |= E1000_RCTL_SECRC;
|
||||
ew32(RCTL, mac_reg);
|
||||
|
||||
ret_val = e1000e_read_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_CTRL_OFFSET,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_CTRL_OFFSET,
|
||||
data | (1 << 0));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1000e_read_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_HD_CTRL,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
data &= ~(0xF << 8);
|
||||
data |= (0xB << 8);
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_HD_CTRL,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Enable jumbo frame workaround in the PHY */
|
||||
e1e_rphy(hw, PHY_REG(769, 20), &data);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(769, 23), &data);
|
||||
data &= ~(0x7F << 5);
|
||||
data |= (0x37 << 5);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(769, 16), &data);
|
||||
data &= ~(1 << 13);
|
||||
data |= (1 << 12);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(776, 20), &data);
|
||||
data &= ~(0x3FF << 2);
|
||||
data |= (0x1A << 2);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0xFE00);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, HV_PM_CTRL, &data);
|
||||
ret_val = e1e_wphy(hw, HV_PM_CTRL, data | (1 << 10));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
} else {
|
||||
/* Write MAC register values back to h/w defaults */
|
||||
mac_reg = er32(FFLT_DBG);
|
||||
mac_reg &= ~(0xF << 14);
|
||||
ew32(FFLT_DBG, mac_reg);
|
||||
|
||||
mac_reg = er32(RCTL);
|
||||
mac_reg &= ~E1000_RCTL_SECRC;
|
||||
ew32(FFLT_DBG, mac_reg);
|
||||
|
||||
ret_val = e1000e_read_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_CTRL_OFFSET,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_CTRL_OFFSET,
|
||||
data & ~(1 << 0));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1000e_read_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_HD_CTRL,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
data &= ~(0xF << 8);
|
||||
data |= (0xB << 8);
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_HD_CTRL,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Write PHY register values back to h/w defaults */
|
||||
e1e_rphy(hw, PHY_REG(769, 20), &data);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(769, 23), &data);
|
||||
data &= ~(0x7F << 5);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(769, 16), &data);
|
||||
data &= ~(1 << 12);
|
||||
data |= (1 << 13);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, PHY_REG(776, 20), &data);
|
||||
data &= ~(0x3FF << 2);
|
||||
data |= (0x8 << 2);
|
||||
ret_val = e1e_wphy(hw, PHY_REG(776, 20), data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1e_wphy(hw, PHY_REG(776, 23), 0x7E00);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
e1e_rphy(hw, HV_PM_CTRL, &data);
|
||||
ret_val = e1e_wphy(hw, HV_PM_CTRL, data & ~(1 << 10));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* re-enable Rx path after enabling/disabling workaround */
|
||||
ret_val = e1e_wphy(hw, PHY_REG(769, 20), phy_reg & ~(1 << 14));
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_lv_phy_workarounds_ich8lan - A series of Phy workarounds to be
|
||||
* done after every PHY reset.
|
||||
**/
|
||||
static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
|
||||
if (hw->mac.type != e1000_pch2lan)
|
||||
goto out;
|
||||
|
||||
/* Set MDIO slow mode before any other MDIO access */
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_lan_init_done_ich8lan - Check for PHY config completion
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -1300,12 +1567,17 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
|
|||
if (ret_val)
|
||||
goto out;
|
||||
break;
|
||||
case e1000_pch2lan:
|
||||
ret_val = e1000_lv_phy_workarounds_ich8lan(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Dummy read to clear the phy wakeup bit after lcd reset */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
if (hw->mac.type >= e1000_pchlan)
|
||||
e1e_rphy(hw, BM_WUC, ®);
|
||||
|
||||
/* Configure the LCD with the extended configuration region in NVM */
|
||||
|
@ -2829,6 +3101,7 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
ew32(FCTTV, hw->fc.pause_time);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82579) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
ew32(FCRTV_PCH, hw->fc.refresh_time);
|
||||
|
||||
|
@ -2892,6 +3165,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
break;
|
||||
case e1000_phy_82577:
|
||||
case e1000_phy_82579:
|
||||
ret_val = e1000_copper_link_setup_82577(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
@ -3399,6 +3673,7 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
/* Clear PHY statistics registers */
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82579) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data);
|
||||
|
@ -3534,3 +3809,22 @@ struct e1000_info e1000_pch_info = {
|
|||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &ich8_nvm_ops,
|
||||
};
|
||||
|
||||
struct e1000_info e1000_pch2_info = {
|
||||
.mac = e1000_pch2lan,
|
||||
.flags = FLAG_IS_ICH
|
||||
| FLAG_HAS_WOL
|
||||
| FLAG_RX_CSUM_ENABLED
|
||||
| FLAG_HAS_CTRLEXT_ON_LOAD
|
||||
| FLAG_HAS_AMT
|
||||
| FLAG_HAS_FLASH
|
||||
| FLAG_HAS_JUMBO_FRAMES
|
||||
| FLAG_APME_IN_WUC,
|
||||
.flags2 = FLAG2_HAS_PHY_STATS,
|
||||
.pba = 18,
|
||||
.max_hw_frame_size = DEFAULT_JUMBO,
|
||||
.get_variants = e1000_get_variants_ich8lan,
|
||||
.mac_ops = &ich8_mac_ops,
|
||||
.phy_ops = &ich8_phy_ops,
|
||||
.nvm_ops = &ich8_nvm_ops,
|
||||
};
|
||||
|
|
|
@ -67,6 +67,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
|
|||
[board_ich9lan] = &e1000_ich9_info,
|
||||
[board_ich10lan] = &e1000_ich10_info,
|
||||
[board_pchlan] = &e1000_pch_info,
|
||||
[board_pch2lan] = &e1000_pch2_info,
|
||||
};
|
||||
|
||||
struct e1000_reg_info {
|
||||
|
@ -2723,6 +2724,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
|
|||
e1e_wphy(hw, 22, phy_data);
|
||||
}
|
||||
|
||||
/* Workaround Si errata on 82579 - configure jumbo frame flow */
|
||||
if (hw->mac.type == e1000_pch2lan) {
|
||||
s32 ret_val;
|
||||
|
||||
if (rctl & E1000_RCTL_LPE)
|
||||
ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
|
||||
else
|
||||
ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
|
||||
}
|
||||
|
||||
/* Setup buffer sizes */
|
||||
rctl &= ~E1000_RCTL_SZ_4096;
|
||||
rctl |= E1000_RCTL_BSEX;
|
||||
|
@ -3118,7 +3129,27 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|||
* with ERT support assuming ERT set to E1000_ERT_2048), or
|
||||
* - the full Rx FIFO size minus one full frame
|
||||
*/
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
|
||||
fc->pause_time = 0xFFFF;
|
||||
else
|
||||
fc->pause_time = E1000_FC_PAUSE_TIME;
|
||||
fc->send_xon = 1;
|
||||
fc->current_mode = fc->requested_mode;
|
||||
|
||||
switch (hw->mac.type) {
|
||||
default:
|
||||
if ((adapter->flags & FLAG_HAS_ERT) &&
|
||||
(adapter->netdev->mtu > ETH_DATA_LEN))
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - (E1000_ERT_2048 << 3)));
|
||||
else
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - adapter->max_frame_size));
|
||||
|
||||
fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
|
||||
fc->low_water = fc->high_water - 8;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
/*
|
||||
* Workaround PCH LOM adapter hangs with certain network
|
||||
* loads. If hangs persist, try disabling Tx flow control.
|
||||
|
@ -3131,26 +3162,15 @@ void e1000e_reset(struct e1000_adapter *adapter)
|
|||
fc->low_water = 0x3000;
|
||||
}
|
||||
fc->refresh_time = 0x1000;
|
||||
} else {
|
||||
if ((adapter->flags & FLAG_HAS_ERT) &&
|
||||
(adapter->netdev->mtu > ETH_DATA_LEN))
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - (E1000_ERT_2048 << 3)));
|
||||
else
|
||||
hwm = min(((pba << 10) * 9 / 10),
|
||||
((pba << 10) - adapter->max_frame_size));
|
||||
|
||||
fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
|
||||
fc->low_water = fc->high_water - 8;
|
||||
break;
|
||||
case e1000_pch2lan:
|
||||
fc->high_water = 0x05C20;
|
||||
fc->low_water = 0x05048;
|
||||
fc->pause_time = 0x0650;
|
||||
fc->refresh_time = 0x0400;
|
||||
break;
|
||||
}
|
||||
|
||||
if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
|
||||
fc->pause_time = 0xFFFF;
|
||||
else
|
||||
fc->pause_time = E1000_FC_PAUSE_TIME;
|
||||
fc->send_xon = 1;
|
||||
fc->current_mode = fc->requested_mode;
|
||||
|
||||
/* Allow time for pending master requests to run */
|
||||
mac->ops.reset_hw(hw);
|
||||
|
||||
|
@ -4918,14 +4938,7 @@ static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
|
|||
int retval = 0;
|
||||
|
||||
/* copy MAC RARs to PHY RARs */
|
||||
for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
|
||||
mac_reg = er32(RAL(i));
|
||||
e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
mac_reg = er32(RAH(i));
|
||||
e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
|
||||
e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
|
||||
}
|
||||
e1000_copy_rx_addrs_to_phy_ich8lan(hw);
|
||||
|
||||
/* copy MAC MTA to PHY MTA */
|
||||
for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
|
||||
|
@ -5976,6 +5989,9 @@ static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
|
|||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
|
||||
|
||||
{ } /* terminate list */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
|
||||
|
|
|
@ -2319,6 +2319,9 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
|
|||
case I82577_E_PHY_ID:
|
||||
phy_type = e1000_phy_82577;
|
||||
break;
|
||||
case I82579_E_PHY_ID:
|
||||
phy_type = e1000_phy_82579;
|
||||
break;
|
||||
default:
|
||||
phy_type = e1000_phy_unknown;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue