summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000/e1000_82575.c
diff options
context:
space:
mode:
authorjfv <jfv@FreeBSD.org>2014-07-28 21:11:18 +0000
committerjfv <jfv@FreeBSD.org>2014-07-28 21:11:18 +0000
commit00e682104eb14211088566f56db127cc292bc3bf (patch)
treee1e530888e00e37f9544ea33cebd0f8d60fd6d25 /sys/dev/e1000/e1000_82575.c
parent37a9f7be2fd32cf24c75d466cacac9ce83a3766b (diff)
downloadFreeBSD-src-00e682104eb14211088566f56db127cc292bc3bf.zip
FreeBSD-src-00e682104eb14211088566f56db127cc292bc3bf.tar.gz
MFC of R267935: Sync the E1000 shared code to Intel internal, and
more importantly add new I218 adapter support to em.
Diffstat (limited to 'sys/dev/e1000/e1000_82575.c')
-rw-r--r--sys/dev/e1000/e1000_82575.c146
1 files changed, 125 insertions, 21 deletions
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 1707236..d79db67 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2013, Intel Corporation
+ Copyright (c) 2001-2014, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -56,7 +56,6 @@ static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw);
static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
-static s32 e1000_init_hw_82575(struct e1000_hw *hw);
static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data);
@@ -120,7 +119,8 @@ static bool e1000_get_i2c_data(u32 *i2cctl);
static const u16 e1000_82580_rxpbs_table[] = {
36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
#define E1000_82580_RXPBS_TABLE_SIZE \
- (sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+ (sizeof(e1000_82580_rxpbs_table) / \
+ sizeof(e1000_82580_rxpbs_table[0]))
/**
@@ -273,6 +273,11 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
hw->mac.ops.check_for_link =
e1000_check_for_link_media_swap;
}
+ if (phy->id == M88E1512_E_PHY_ID) {
+ ret_val = e1000_initialize_M88E1512_phy(hw);
+ if (ret_val)
+ goto out;
+ }
break;
case IGP03E1000_E_PHY_ID:
case IGP04E1000_E_PHY_ID:
@@ -450,6 +455,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
else
mac->ops.reset_hw = e1000_reset_hw_82575;
/* hw initialization */
+ if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
+ mac->ops.init_hw = e1000_init_hw_i210;
+ else
mac->ops.init_hw = e1000_init_hw_82575;
/* link setup */
mac->ops.setup_link = e1000_setup_link_generic;
@@ -750,6 +758,7 @@ out:
static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
+ struct e1000_phy_info *phy = &hw->phy;
DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
@@ -772,7 +781,11 @@ static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
goto out;
ret_val = hw->phy.ops.commit(hw);
+ if (ret_val)
+ goto out;
+ if (phy->id == M88E1512_E_PHY_ID)
+ ret_val = e1000_initialize_M88E1512_phy(hw);
out:
return ret_val;
}
@@ -879,7 +892,6 @@ out:
static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
u32 data;
DEBUGFUNC("e1000_set_d0_lplu_state_82580");
@@ -907,7 +919,7 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
}
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
- return ret_val;
+ return E1000_SUCCESS;
}
/**
@@ -927,7 +939,6 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val = E1000_SUCCESS;
u32 data;
DEBUGFUNC("e1000_set_d3_lplu_state_82580");
@@ -955,7 +966,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
}
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data);
- return ret_val;
+ return E1000_SUCCESS;
}
/**
@@ -969,7 +980,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
**/
static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_acquire_nvm_82575");
@@ -991,6 +1002,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
DEBUGOUT("Nvm bit banging access error detected and cleared.\n");
}
}
+
if (hw->mac.type == e1000_82580) {
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
if (eecd & E1000_EECD_BLOCKED) {
@@ -1001,7 +1013,6 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
}
}
-
ret_val = e1000_acquire_nvm_generic(hw);
if (ret_val)
e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
@@ -1115,7 +1126,6 @@ static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
{
s32 timeout = PHY_CFG_TIMEOUT;
- s32 ret_val = E1000_SUCCESS;
u32 mask = E1000_NVM_CFG_DONE_PORT_0;
DEBUGFUNC("e1000_get_cfg_done_82575");
@@ -1140,7 +1150,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
(hw->phy.type == e1000_phy_igp_3))
e1000_phy_init_script_igp3(hw);
- return ret_val;
+ return E1000_SUCCESS;
}
/**
@@ -1466,7 +1476,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
*
* This inits the hardware readying it for operation.
**/
-static s32 e1000_init_hw_82575(struct e1000_hw *hw)
+s32 e1000_init_hw_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val;
@@ -1985,7 +1995,7 @@ static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
**/
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw)
{
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
DEBUGFUNC("e1000_read_mac_addr_82575");
@@ -2478,11 +2488,17 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
ctrl |= E1000_CTRL_RST;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
- /* Add delay to insure DEV_RST has time to complete */
- if (global_device_reset)
- msec_delay(5);
+ switch (hw->device_id) {
+ case E1000_DEV_ID_DH89XXCC_SGMII:
+ break;
+ default:
+ E1000_WRITE_FLUSH(hw);
+ break;
+ }
+
+ /* Add delay to insure DEV_RST or RST has time to complete */
+ msec_delay(5);
ret_val = e1000_get_auto_rd_done_generic(hw);
if (ret_val) {
@@ -2617,7 +2633,7 @@ out:
**/
static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw)
{
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
u16 eeprom_regions_count = 1;
u16 j, nvm_data;
u16 nvm_offset;
@@ -2757,7 +2773,7 @@ out:
static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 address,
u16 *data, bool read)
{
- s32 ret_val = E1000_SUCCESS;
+ s32 ret_val;
DEBUGFUNC("__e1000_access_emi_reg");
@@ -2787,6 +2803,95 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
}
/**
+ * e1000_initialize_M88E1512_phy - Initialize M88E1512 PHY
+ * @hw: pointer to the HW structure
+ *
+ * Initialize Marverl 1512 to work correctly with Avoton.
+ **/
+s32 e1000_initialize_M88E1512_phy(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_initialize_M88E1512_phy");
+
+ /* Check if this is correct PHY. */
+ if (phy->id != M88E1512_E_PHY_ID)
+ goto out;
+
+ /* Switch to PHY page 0xFF. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FF);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x214B);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2144);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0x0C28);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2146);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xB233);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x214D);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_2, 0xCC0C);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_1, 0x2159);
+ if (ret_val)
+ goto out;
+
+ /* Switch to PHY page 0xFB. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x00FB);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_CFG_REG_3, 0x000D);
+ if (ret_val)
+ goto out;
+
+ /* Switch to PHY page 0x12. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0x12);
+ if (ret_val)
+ goto out;
+
+ /* Change mode to SGMII-to-Copper */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1512_MODE, 0x8001);
+ if (ret_val)
+ goto out;
+
+ /* Return the PHY to page 0. */
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0);
+ if (ret_val)
+ goto out;
+
+ ret_val = phy->ops.commit(hw);
+ if (ret_val) {
+ DEBUGOUT("Error committing the PHY changes\n");
+ return ret_val;
+ }
+
+ msec_delay(1000);
+out:
+ return ret_val;
+}
+
+/**
* e1000_set_eee_i350 - Enable/disable EEE support
* @hw: pointer to the HW structure
*
@@ -2795,7 +2900,6 @@ s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 *data)
**/
s32 e1000_set_eee_i350(struct e1000_hw *hw)
{
- s32 ret_val = E1000_SUCCESS;
u32 ipcnfg, eeer;
DEBUGFUNC("e1000_set_eee_i350");
@@ -2828,7 +2932,7 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw)
E1000_READ_REG(hw, E1000_EEER);
out:
- return ret_val;
+ return E1000_SUCCESS;
}
/**
OpenPOWER on IntegriCloud