summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000/e1000_82575.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/e1000/e1000_82575.c')
-rw-r--r--sys/dev/e1000/e1000_82575.c195
1 files changed, 110 insertions, 85 deletions
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 75fe0a4..a04e3fa 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2011, Intel Corporation
+ Copyright (c) 2001-2012, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,12 @@
* 82575GB Gigabit Network Connection
* 82576 Gigabit Network Connection
* 82576 Quad Port Gigabit Mezzanine Adapter
+ * 82580 Gigabit Network Connection
+ * I350 Gigabit Network Connection
*/
#include "e1000_api.h"
+#include "e1000_i210.h"
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
@@ -162,6 +165,9 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
DEBUGFUNC("e1000_init_phy_params_82575");
+ phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
+ phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
+
if (hw->phy.media_type != e1000_media_type_copper) {
phy->type = e1000_phy_none;
goto out;
@@ -195,12 +201,22 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
- } else if (hw->mac.type >= e1000_82580) {
- phy->ops.read_reg = e1000_read_phy_reg_82580;
- phy->ops.write_reg = e1000_write_phy_reg_82580;
} else {
- phy->ops.read_reg = e1000_read_phy_reg_igp;
- phy->ops.write_reg = e1000_write_phy_reg_igp;
+ switch (hw->mac.type) {
+ case e1000_82580:
+ case e1000_i350:
+ phy->ops.read_reg = e1000_read_phy_reg_82580;
+ phy->ops.write_reg = e1000_write_phy_reg_82580;
+ break;
+ case e1000_i210:
+ case e1000_i211:
+ phy->ops.read_reg = e1000_read_phy_reg_gs40g;
+ phy->ops.write_reg = e1000_write_phy_reg_gs40g;
+ break;
+ default:
+ phy->ops.read_reg = e1000_read_phy_reg_igp;
+ phy->ops.write_reg = e1000_write_phy_reg_igp;
+ }
}
/* Set phy->phy_addr and phy->id. */
@@ -245,6 +261,15 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
break;
+ case I210_I_PHY_ID:
+ phy->type = e1000_phy_i210;
+ phy->ops.check_polarity = e1000_check_polarity_m88;
+ phy->ops.get_info = e1000_get_phy_info_m88;
+ phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
+ phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
+ phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
+ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
+ break;
default:
ret_val = -E1000_ERR_PHY;
goto out;
@@ -281,28 +306,32 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
size = 15;
nvm->word_size = 1 << size;
- nvm->opcode_bits = 8;
- nvm->delay_usec = 1;
- switch (nvm->override) {
- case e1000_nvm_override_spi_large:
- nvm->page_size = 32;
- nvm->address_bits = 16;
- break;
- case e1000_nvm_override_spi_small:
- nvm->page_size = 8;
- nvm->address_bits = 8;
- break;
- default:
- nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
- nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
- break;
- }
-
- nvm->type = e1000_nvm_eeprom_spi;
-
- if (nvm->word_size == (1 << 15))
- nvm->page_size = 128;
+ if (hw->mac.type < e1000_i210) {
+ nvm->opcode_bits = 8;
+ nvm->delay_usec = 1;
+
+ switch (nvm->override) {
+ case e1000_nvm_override_spi_large:
+ nvm->page_size = 32;
+ nvm->address_bits = 16;
+ break;
+ case e1000_nvm_override_spi_small:
+ nvm->page_size = 8;
+ nvm->address_bits = 8;
+ break;
+ default:
+ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
+ nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
+ 16 : 8;
+ break;
+ }
+ if (nvm->word_size == (1 << 15))
+ nvm->page_size = 128;
+ nvm->type = e1000_nvm_eeprom_spi;
+ } else {
+ nvm->type = e1000_nvm_flash_hw;
+ }
/* Function Pointers */
nvm->ops.acquire = e1000_acquire_nvm_82575;
nvm->ops.release = e1000_release_nvm_82575;
@@ -316,7 +345,7 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
nvm->ops.update = e1000_update_nvm_checksum_generic;
nvm->ops.valid_led_default = e1000_valid_led_default_82575;
- /* override genric family function pointers for specific descendants */
+ /* override generic family function pointers for specific descendants */
switch (hw->mac.type) {
case e1000_82580:
nvm->ops.validate = e1000_validate_nvm_checksum_82580;
@@ -368,8 +397,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->has_fwsm = TRUE;
/* ARC supported; valid only if manageability features are enabled. */
mac->arc_subsystem_valid =
- (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
- ? TRUE : FALSE;
+ !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
/* Function pointers */
@@ -394,8 +422,6 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
/* check for link */
mac->ops.check_for_link = e1000_check_for_link_82575;
- /* receive address register setting */
- mac->ops.rar_set = e1000_rar_set_generic;
/* read mac address */
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* configure collision distance */
@@ -428,6 +454,13 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
/* link info */
mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
+ /* acquire SW_FW sync */
+ mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575;
+ mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
+ if (mac->type >= e1000_i210) {
+ mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
+ mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
+ }
/* set lan id for port to determine which phy lock to use */
hw->mac.ops.set_lan_id(hw);
@@ -470,7 +503,7 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
else if (hw->bus.func == E1000_FUNC_3)
mask = E1000_SWFW_PHY3_SM;
- return e1000_acquire_swfw_sync_82575(hw, mask);
+ return hw->mac.ops.acquire_swfw_sync(hw, mask);
}
/**
@@ -492,7 +525,7 @@ static void e1000_release_phy_82575(struct e1000_hw *hw)
else if (hw->bus.func == E1000_FUNC_3)
mask = E1000_SWFW_PHY3_SM;
- e1000_release_swfw_sync_82575(hw, mask);
+ hw->mac.ops.release_swfw_sync(hw, mask);
}
/**
@@ -796,7 +829,7 @@ 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;
- u16 data;
+ u32 data;
DEBUGFUNC("e1000_set_d0_lplu_state_82580");
@@ -844,7 +877,7 @@ 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;
- u16 data;
+ u32 data;
DEBUGFUNC("e1000_set_d3_lplu_state_82580");
@@ -918,11 +951,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
}
- switch (hw->mac.type) {
- default:
- ret_val = e1000_acquire_nvm_generic(hw);
- }
-
+ ret_val = e1000_acquire_nvm_generic(hw);
if (ret_val)
e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
@@ -941,10 +970,8 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_release_nvm_82575");
- switch (hw->mac.type) {
- default:
- e1000_release_nvm_generic(hw);
- }
+ e1000_release_nvm_generic(hw);
+
e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
}
@@ -1058,7 +1085,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
DEBUGOUT("MNG configuration cycle has not completed.\n");
/* If EEPROM is not marked present, init the PHY manually */
- if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
+ if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
(hw->phy.type == e1000_phy_igp_3))
e1000_phy_init_script_igp3(hw);
@@ -1115,6 +1142,7 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
* continue to check for link.
*/
hw->mac.get_link_status = !hw->mac.serdes_has_link;
+
} else {
ret_val = e1000_check_for_copper_link_generic(hw);
}
@@ -1168,11 +1196,6 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
- /* Set up defaults for the return values of this function */
- mac->serdes_has_link = FALSE;
- *speed = 0;
- *duplex = 0;
-
/*
* Read the PCS Status register for link state. For non-copper mode,
* the status register is not accurate. The PCS status register is
@@ -1181,11 +1204,9 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
/*
- * The link up bit determines when link is up on autoneg. The sync ok
- * gets set once both sides sync up and agree upon link. Stable link
- * can be determined by checking for both link up and link sync ok
+ * The link up bit determines when link is up on autoneg.
*/
- if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
+ if (pcs & E1000_PCS_LSTS_LINK_OK) {
mac->serdes_has_link = TRUE;
/* Detect and store PCS speed */
@@ -1201,6 +1222,10 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
+ } else {
+ mac->serdes_has_link = FALSE;
+ *speed = 0;
+ *duplex = 0;
}
return E1000_SUCCESS;
@@ -1293,7 +1318,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
}
/* If EEPROM is not present, run manual init scripts */
- if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
+ if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
e1000_reset_init_script_82575(hw);
/* Clear any pending interrupt events. */
@@ -1396,6 +1421,7 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
}
}
switch (hw->phy.type) {
+ case e1000_phy_i210:
case e1000_phy_m88:
if (hw->phy.id == I347AT4_E_PHY_ID ||
hw->phy.id == M88E1112_E_PHY_ID ||
@@ -1605,31 +1631,28 @@ static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
}
/* Read Init Control Word #3*/
hw->nvm.ops.read(hw, init_ctrl_wd_3_offset, 1, &init_ctrl_wd_3);
+
+ /*
+ * Align link mode bits to
+ * their CTRL_EXT location.
+ */
current_link_mode = init_ctrl_wd_3;
+ current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET -
+ init_ctrl_wd_3_bit_offset);
+ current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK;
+
/*
* Switch to CSR for all but internal PHY.
*/
- if ((init_ctrl_wd_3 << (E1000_CTRL_EXT_LINK_MODE_OFFSET -
- init_ctrl_wd_3_bit_offset)) !=
- E1000_CTRL_EXT_LINK_MODE_GMII) {
- current_link_mode = ctrl_ext;
- init_ctrl_wd_3_bit_offset =
- E1000_CTRL_EXT_LINK_MODE_OFFSET;
- }
+ if (current_link_mode != E1000_CTRL_EXT_LINK_MODE_GMII)
+ /* Take link mode from CSR */
+ current_link_mode = ctrl_ext &
+ E1000_CTRL_EXT_LINK_MODE_MASK;
} else {
/* Take link mode from CSR */
- current_link_mode = ctrl_ext;
- init_ctrl_wd_3_bit_offset = E1000_CTRL_EXT_LINK_MODE_OFFSET;
+ current_link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
}
- /*
- * Align link mode bits to
- * their CTRL_EXT location.
- */
- current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET -
- init_ctrl_wd_3_bit_offset);
- current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK;
-
switch (current_link_mode) {
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
@@ -2331,7 +2354,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
msec_delay(10);
/* Determine whether or not a global dev reset is requested */
- if (global_device_reset && e1000_acquire_swfw_sync_82575(hw,
+ if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
swmbsw_mask))
global_device_reset = FALSE;
@@ -2359,7 +2382,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
}
/* If EEPROM is not present, run manual init scripts */
- if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
+ if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
e1000_reset_init_script_82575(hw);
/* clear global device reset status bit */
@@ -2378,7 +2401,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
/* Release semaphore */
if (global_device_reset)
- e1000_release_swfw_sync_82575(hw, swmbsw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
return ret_val;
}
@@ -2538,7 +2561,7 @@ static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
goto out;
}
- if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) {
+ if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
/* set compatibility bit to validate checksums appropriately */
nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
@@ -2737,6 +2760,7 @@ s32 e1000_set_i2c_bb(struct e1000_hw *hw)
* e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to read
+ * @dev_addr: device address
* @data: value read
*
* Performs byte read operation over I2C interface at
@@ -2750,14 +2774,14 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
u32 retry = 1;
u16 swfw_mask = 0;
- bool nack = 1;
+ bool nack = TRUE;
DEBUGFUNC("e1000_read_i2c_byte_generic");
swfw_mask = E1000_SWFW_PHY0_SM;
do {
- if (e1000_acquire_swfw_sync_82575(hw, swfw_mask)
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
!= E1000_SUCCESS) {
status = E1000_ERR_SWFW_SYNC;
goto read_byte_out;
@@ -2805,7 +2829,7 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
break;
fail:
- e1000_release_swfw_sync_82575(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
msec_delay(100);
e1000_i2c_bus_clear(hw);
retry++;
@@ -2816,7 +2840,7 @@ fail:
} while (retry < max_retry);
- e1000_release_swfw_sync_82575(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
read_byte_out:
@@ -2827,6 +2851,7 @@ read_byte_out:
* e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
* @hw: pointer to hardware structure
* @byte_offset: byte offset to write
+ * @dev_addr: device address
* @data: value to write
*
* Performs byte write operation over I2C interface at
@@ -2844,7 +2869,7 @@ s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
swfw_mask = E1000_SWFW_PHY0_SM;
- if (e1000_acquire_swfw_sync_82575(hw, swfw_mask) != E1000_SUCCESS) {
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
status = E1000_ERR_SWFW_SYNC;
goto write_byte_out;
}
@@ -2888,7 +2913,7 @@ fail:
DEBUGOUT("I2C byte write error.\n");
} while (retry < max_retry);
- e1000_release_swfw_sync_82575(hw, swfw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
write_byte_out:
@@ -3020,7 +3045,7 @@ static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
u32 i = 0;
u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
u32 timeout = 10;
- bool ack = 1;
+ bool ack = TRUE;
DEBUGFUNC("e1000_get_i2c_ack");
@@ -3040,7 +3065,7 @@ static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
return E1000_ERR_I2C;
ack = e1000_get_i2c_data(&i2cctl);
- if (ack == 1) {
+ if (ack) {
DEBUGOUT("I2C ack was not received.\n");
status = E1000_ERR_I2C;
}
OpenPOWER on IntegriCloud