diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-09-12 02:38:15 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-09-12 02:38:15 +0000 |
commit | a355e2fc1f55c5969777681faf6f6a87a108a67b (patch) | |
tree | 8031f06ed56a783a8254faedca4892ddde1b394e /sys/dev | |
parent | 23a4d43d181033dd9927e04c7e54b9631f422edc (diff) |
Add support for the 88E1512/88E1514 phys using the 1512 init sequence
from the Intel code in FreeBSD.
Tested by Paul Levlin on a machine with I354.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_em_hw.c | 103 | ||||
-rw-r--r-- | sys/dev/pci/if_em_hw.h | 12 |
2 files changed, 111 insertions, 4 deletions
diff --git a/sys/dev/pci/if_em_hw.c b/sys/dev/pci/if_em_hw.c index 5f279bcbd64..3e7fdb15121 100644 --- a/sys/dev/pci/if_em_hw.c +++ b/sys/dev/pci/if_em_hw.c @@ -31,7 +31,7 @@ *******************************************************************************/ -/* $OpenBSD: if_em_hw.c,v 1.87 2015/08/05 18:31:14 sf Exp $ */ +/* $OpenBSD: if_em_hw.c,v 1.88 2015/09/12 02:38:14 jsg Exp $ */ /* * if_em_hw.c Shared functions for accessing and configuring the MAC */ @@ -182,7 +182,7 @@ int32_t em_get_pcs_speed_and_duplex_82575(struct em_hw *, uint16_t *, int32_t em_set_eee_i350(struct em_hw *); int32_t em_set_eee_pchlan(struct em_hw *); int32_t em_valid_nvm_bank_detect_ich8lan(struct em_hw *, uint32_t *); - +int32_t em_initialize_M88E1512_phy(struct em_hw *); /* IGP cable length table */ static const uint16_t @@ -229,6 +229,7 @@ em_set_phy_type(struct em_hw *hw) case M88E1111_I_PHY_ID: case M88E1112_E_PHY_ID: case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: case I210_I_PHY_ID: case I347AT4_E_PHY_ID: hw->phy_type = em_phy_m88; @@ -5272,6 +5273,12 @@ em_phy_reset(struct em_hw *hw) em_gate_hw_phy_config_ich8lan(hw, FALSE); } + if (hw->phy_id == M88E1512_E_PHY_ID) { + ret_val = em_initialize_M88E1512_phy(hw); + if (ret_val) + return ret_val; + } + return E1000_SUCCESS; } @@ -5410,7 +5417,8 @@ em_match_gig_phy(struct em_hw *hw) hw->phy_id == I347AT4_E_PHY_ID || hw->phy_id == I350_I_PHY_ID || hw->phy_id == M88E1112_E_PHY_ID || - hw->phy_id == M88E1543_E_PHY_ID) { + hw->phy_id == M88E1543_E_PHY_ID || + hw->phy_id == M88E1512_E_PHY_ID) { uint32_t mdic; mdic = EM_READ_REG(hw, E1000_MDICNFG); @@ -10896,3 +10904,92 @@ out: return ret_val; } +/** + * em_initialize_M88E1512_phy - Initialize M88E1512 PHY + * @hw: pointer to the HW structure + * + * Initialize Marvell 1512 to work correctly with Avoton. + **/ +int32_t +em_initialize_M88E1512_phy(struct em_hw *hw) +{ + int32_t ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_initialize_M88E1512_phy"); + + /* Check if this is correct PHY. */ + if (hw->phy_id != M88E1512_E_PHY_ID) + goto out; + + /* Switch to PHY page 0xFF. */ + ret_val = em_write_phy_reg(hw, M88E1543_PAGE_ADDR, 0x00FF); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_2, 0x214B); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_1, 0x2144); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_2, 0x0C28); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_1, 0x2146); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_2, 0xB233); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_1, 0x214D); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_2, 0xCC0C); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_1, 0x2159); + if (ret_val) + goto out; + + /* Switch to PHY page 0xFB. */ + ret_val = em_write_phy_reg(hw, M88E1543_PAGE_ADDR, 0x00FB); + if (ret_val) + goto out; + + ret_val = em_write_phy_reg(hw, M88E1512_CFG_REG_3, 0x000D); + if (ret_val) + goto out; + + /* Switch to PHY page 0x12. */ + ret_val = em_write_phy_reg(hw, M88E1543_PAGE_ADDR, 0x12); + if (ret_val) + goto out; + + /* Change mode to SGMII-to-Copper */ + ret_val = em_write_phy_reg(hw, M88E1512_MODE, 0x8001); + if (ret_val) + goto out; + + /* Return the PHY to page 0. */ + ret_val = em_write_phy_reg(hw, M88E1543_PAGE_ADDR, 0); + if (ret_val) + goto out; + + ret_val = em_phy_hw_reset(hw); + if (ret_val) { + DEBUGOUT("Error committing the PHY changes\n"); + return ret_val; + } + + msec_delay(1000); +out: + return ret_val; +} + diff --git a/sys/dev/pci/if_em_hw.h b/sys/dev/pci/if_em_hw.h index 03877f6745a..a44a37ac8cd 100644 --- a/sys/dev/pci/if_em_hw.h +++ b/sys/dev/pci/if_em_hw.h @@ -31,7 +31,7 @@ *******************************************************************************/ -/* $OpenBSD: if_em_hw.h,v 1.66 2015/08/05 18:31:14 sf Exp $ */ +/* $OpenBSD: if_em_hw.h,v 1.67 2015/09/12 02:38:14 jsg Exp $ */ /* $FreeBSD: if_em_hw.h,v 1.15 2005/05/26 23:32:02 tackerman Exp $ */ /* if_em_hw.h @@ -2802,6 +2802,15 @@ struct em_host_command_info { #define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ #define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ +#define M88E1543_PAGE_ADDR 0x16 /* Page Offset Register */ +#define M88E1543_EEE_CTRL_1 0x0 +#define M88E1543_EEE_CTRL_1_MS 0x0001 /* EEE Master/Slave */ + +#define M88E1512_CFG_REG_1 0x0010 +#define M88E1512_CFG_REG_2 0x0011 +#define M88E1512_CFG_REG_3 0x0007 +#define M88E1512_MODE 0x0014 + /* BME1000 PHY Specific Control Register */ #define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ #define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ @@ -3424,6 +3433,7 @@ struct em_host_command_info { #define I210_I_PHY_ID 0x01410C00 #define IGP04E1000_E_PHY_ID 0x02A80391 #define M88E1141_E_PHY_ID 0x01410CD0 +#define M88E1512_E_PHY_ID 0x01410DD0 /* Bits... * 15-5: page |