summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorchenlu chen - Sun Microsystems - Beijing China <Chenlu.Chen@Sun.COM>2009-01-20 09:31:31 +0800
committerchenlu chen - Sun Microsystems - Beijing China <Chenlu.Chen@Sun.COM>2009-01-20 09:31:31 +0800
commit80a11ad227f9c82cd6e7cf5c8913a37f00b7af0e (patch)
treede77136b4fdaad7ede944841dba5612ac26006b2 /usr/src
parent48794f22b496c8c5aaa74b67fdff1a4c0409a7a7 (diff)
downloadillumos-joyent-80a11ad227f9c82cd6e7cf5c8913a37f00b7af0e.tar.gz
6708291 igb needs to support the new chipset Kawela
6737111 panic in igb_main.c(line: 1872): assertion failed: tx_ring->tcb_free == tx_ring->free_list_size 6740801 igb's rx bind function does not set newly desballoc-ed mblk to be ip header aligned
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/igb/igb_82575.c572
-rw-r--r--usr/src/uts/common/io/igb/igb_82575.h188
-rw-r--r--usr/src/uts/common/io/igb/igb_api.c279
-rw-r--r--usr/src/uts/common/io/igb/igb_api.h27
-rw-r--r--usr/src/uts/common/io/igb/igb_buf.c15
-rw-r--r--usr/src/uts/common/io/igb/igb_debug.c13
-rw-r--r--usr/src/uts/common/io/igb/igb_defines.h151
-rw-r--r--usr/src/uts/common/io/igb/igb_hw.h282
-rw-r--r--usr/src/uts/common/io/igb/igb_mac.c342
-rw-r--r--usr/src/uts/common/io/igb/igb_mac.h22
-rw-r--r--usr/src/uts/common/io/igb/igb_main.c367
-rw-r--r--usr/src/uts/common/io/igb/igb_manage.c37
-rw-r--r--usr/src/uts/common/io/igb/igb_manage.h13
-rw-r--r--usr/src/uts/common/io/igb/igb_ndd.c8
-rw-r--r--usr/src/uts/common/io/igb/igb_nvm.c215
-rw-r--r--usr/src/uts/common/io/igb/igb_nvm.h20
-rw-r--r--usr/src/uts/common/io/igb/igb_osdep.c36
-rw-r--r--usr/src/uts/common/io/igb/igb_osdep.h38
-rw-r--r--usr/src/uts/common/io/igb/igb_phy.c991
-rw-r--r--usr/src/uts/common/io/igb/igb_phy.h50
-rw-r--r--usr/src/uts/common/io/igb/igb_regs.h320
-rw-r--r--usr/src/uts/common/io/igb/igb_rx.c30
-rw-r--r--usr/src/uts/common/io/igb/igb_sw.h66
-rw-r--r--usr/src/uts/common/io/igb/igb_tx.c30
24 files changed, 2325 insertions, 1787 deletions
diff --git a/usr/src/uts/common/io/igb/igb_82575.c b/usr/src/uts/common/io/igb/igb_82575.c
index beae6e9d87..e68973fb49 100644
--- a/usr/src/uts/common/io/igb/igb_82575.c
+++ b/usr/src/uts/common/io/igb/igb_82575.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,21 +22,20 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.61 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.94 v2008-10-7 */
/*
- * e1000_82575
- * e1000_82576
+ * 82575EB Gigabit Network Connection
+ * 82575EB Gigabit Backplane Connection
+ * 82575GB Gigabit Network Connection
+ * 82576 Gigabit Network Connection
*/
#include "igb_api.h"
-#include "igb_82575.h"
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
@@ -53,12 +52,12 @@ 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);
-static void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index);
static s32 e1000_reset_hw_82575(struct e1000_hw *hw);
static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
bool active);
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw);
+static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
u32 offset, u16 data);
static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
@@ -72,23 +71,20 @@ static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
-
-
-struct e1000_dev_spec_82575 {
- bool sgmii_active;
-};
+static void e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count);
+static void e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count);
+void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
/*
* e1000_init_phy_params_82575 - Init PHY func ptrs.
* @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
*/
static s32
e1000_init_phy_params_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_82575");
@@ -97,27 +93,27 @@ e1000_init_phy_params_82575(struct e1000_hw *hw)
phy->type = e1000_phy_none;
goto out;
} else {
- func->power_up_phy = e1000_power_up_phy_copper;
- func->power_down_phy = e1000_power_down_phy_copper_82575;
+ phy->ops.power_up = e1000_power_up_phy_copper;
+ phy->ops.power_down = e1000_power_down_phy_copper_82575;
}
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 100;
- func->acquire_phy = e1000_acquire_phy_82575;
- func->check_reset_block = e1000_check_reset_block_generic;
- func->commit_phy = e1000_phy_sw_reset_generic;
- func->get_cfg_done = e1000_get_cfg_done_82575;
- func->release_phy = e1000_release_phy_82575;
+ phy->ops.acquire = e1000_acquire_phy_82575;
+ phy->ops.check_reset_block = e1000_check_reset_block_generic;
+ phy->ops.commit = e1000_phy_sw_reset_generic;
+ phy->ops.get_cfg_done = e1000_get_cfg_done_82575;
+ phy->ops.release = e1000_release_phy_82575;
if (e1000_sgmii_active_82575(hw)) {
- func->reset_phy = e1000_phy_hw_reset_sgmii_82575;
- func->read_phy_reg = e1000_read_phy_reg_sgmii_82575;
- func->write_phy_reg = e1000_write_phy_reg_sgmii_82575;
+ phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
+ phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
+ phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
} else {
- func->reset_phy = e1000_phy_hw_reset_generic;
- func->read_phy_reg = e1000_read_phy_reg_igp;
- func->write_phy_reg = e1000_write_phy_reg_igp;
+ phy->ops.reset = e1000_phy_hw_reset_generic;
+ 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. */
@@ -127,19 +123,20 @@ e1000_init_phy_params_82575(struct e1000_hw *hw)
switch (phy->id) {
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
- func->check_polarity = e1000_check_polarity_m88;
- func->get_phy_info = e1000_get_phy_info_m88;
- func->get_cable_length = e1000_get_cable_length_m88;
- func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;
+ 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;
+ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
+ case IGP04E1000_E_PHY_ID:
phy->type = e1000_phy_igp_3;
- func->check_polarity = e1000_check_polarity_igp;
- func->get_phy_info = e1000_get_phy_info_igp;
- func->get_cable_length = e1000_get_cable_length_igp_2;
- func->force_speed_duplex = e1000_phy_force_speed_duplex_igp;
- func->set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
- func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
+ phy->ops.check_polarity = e1000_check_polarity_igp;
+ phy->ops.get_info = e1000_get_phy_info_igp;
+ phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
+ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
+ phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
+ phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
break;
default:
ret_val = -E1000_ERR_PHY;
@@ -153,14 +150,11 @@ out:
/*
* e1000_init_nvm_params_82575 - Init NVM func ptrs.
* @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
*/
static s32
e1000_init_nvm_params_82575(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
- struct e1000_functions *func = &hw->func;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
u16 size;
@@ -200,13 +194,13 @@ e1000_init_nvm_params_82575(struct e1000_hw *hw)
nvm->word_size = 1 << size;
/* Function Pointers */
- func->acquire_nvm = e1000_acquire_nvm_82575;
- func->read_nvm = e1000_read_nvm_eerd;
- func->release_nvm = e1000_release_nvm_82575;
- func->update_nvm = e1000_update_nvm_checksum_generic;
- func->valid_led_default = e1000_valid_led_default_generic;
- func->validate_nvm = e1000_validate_nvm_checksum_generic;
- func->write_nvm = e1000_write_nvm_spi;
+ nvm->ops.acquire = e1000_acquire_nvm_82575;
+ nvm->ops.read = e1000_read_nvm_eerd;
+ nvm->ops.release = e1000_release_nvm_82575;
+ nvm->ops.update = e1000_update_nvm_checksum_generic;
+ nvm->ops.valid_led_default = e1000_valid_led_default_82575;
+ nvm->ops.validate = e1000_validate_nvm_checksum_generic;
+ nvm->ops.write = e1000_write_nvm_spi;
return (E1000_SUCCESS);
}
@@ -214,39 +208,26 @@ e1000_init_nvm_params_82575(struct e1000_hw *hw)
/*
* e1000_init_mac_params_82575 - Init MAC func ptrs.
* @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
*/
static s32
e1000_init_mac_params_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
- struct e1000_functions *func = &hw->func;
- struct e1000_dev_spec_82575 *dev_spec;
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
u32 ctrl_ext = 0;
- s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82575");
- hw->dev_spec_size = sizeof (struct e1000_dev_spec_82575);
-
- /* Device-specific structure allocation */
- ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
- if (ret_val)
- goto out;
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
/* Set media type */
/*
* The 82575 uses bits 22:23 for link mode. The mode can be changed
* based on the EEPROM. We cannot rely upon device ID. There
* is no distinguishable difference between fiber and internal
* SerDes mode on the 82575. There can be an external PHY attached
- * on the SGMII interface. For this, we'll set sgmii_active to TRUE.
+ * on the SGMII interface. For this, we'll set sgmii_active to true.
*/
hw->phy.media_type = e1000_media_type_copper;
- dev_spec->sgmii_active = FALSE;
+ dev_spec->sgmii_active = false;
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) ==
@@ -254,7 +235,7 @@ e1000_init_mac_params_82575(struct e1000_hw *hw)
hw->phy.media_type = e1000_media_type_internal_serdes;
ctrl_ext |= E1000_CTRL_I2C_ENA;
} else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) {
- dev_spec->sgmii_active = TRUE;
+ dev_spec->sgmii_active = true;
ctrl_ext |= E1000_CTRL_I2C_ENA;
} else {
ctrl_ext &= ~E1000_CTRL_I2C_ENA;
@@ -265,85 +246,84 @@ e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
+ if (mac->type == e1000_82576)
+ mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
/* Set if part includes ASF firmware */
- mac->asf_firmware_present = TRUE;
+ mac->asf_firmware_present = true;
/* Set if manageability features are enabled. */
mac->arc_subsystem_valid =
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
- ? TRUE : FALSE;
+ ? true : false;
/* Function pointers */
/* bus type/speed/width */
- func->get_bus_info = e1000_get_bus_info_pcie_generic;
+ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
/* reset */
- func->reset_hw = e1000_reset_hw_82575;
+ mac->ops.reset_hw = e1000_reset_hw_82575;
/* hw initialization */
- func->init_hw = e1000_init_hw_82575;
+ mac->ops.init_hw = e1000_init_hw_82575;
/* link setup */
- func->setup_link = e1000_setup_link_generic;
+ mac->ops.setup_link = e1000_setup_link_generic;
/* physical interface link setup */
- func->setup_physical_interface =
+ mac->ops.setup_physical_interface =
(hw->phy.media_type == e1000_media_type_copper)
? e1000_setup_copper_link_82575
: e1000_setup_fiber_serdes_link_82575;
+ /* physical interface shutdown */
+ mac->ops.shutdown_serdes = e1000_shutdown_fiber_serdes_link_82575;
/* check for link */
- func->check_for_link = e1000_check_for_link_82575;
+ mac->ops.check_for_link = e1000_check_for_link_82575;
/* receive address register setting */
- func->rar_set = e1000_rar_set_82575;
+ mac->ops.rar_set = e1000_rar_set_generic;
/* read mac address */
- func->read_mac_addr = e1000_read_mac_addr_82575;
+ mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* multicast address update */
- func->update_mc_addr_list = e1000_update_mc_addr_list_generic;
+ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82575;
/* writing VFTA */
- func->write_vfta = e1000_write_vfta_generic;
+ mac->ops.write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
- func->clear_vfta = e1000_clear_vfta_generic;
+ mac->ops.clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
- func->mta_set = e1000_mta_set_generic;
+ mac->ops.mta_set = e1000_mta_set_generic;
/* blink LED */
- func->blink_led = e1000_blink_led_generic;
+ mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
- func->setup_led = e1000_setup_led_generic;
+ mac->ops.setup_led = e1000_setup_led_generic;
/* cleanup LED */
- func->cleanup_led = e1000_cleanup_led_generic;
+ mac->ops.cleanup_led = e1000_cleanup_led_generic;
/* turn on/off LED */
- func->led_on = e1000_led_on_generic;
- func->led_off = e1000_led_off_generic;
- /* remove device */
- func->remove_device = e1000_remove_device_generic;
+ mac->ops.led_on = e1000_led_on_generic;
+ mac->ops.led_off = e1000_led_off_generic;
/* clear hardware counters */
- func->clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
+ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
/* link info */
- func->get_link_up_info = e1000_get_link_up_info_82575;
+ mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
-out:
- return (ret_val);
+ return (E1000_SUCCESS);
}
/*
* e1000_init_function_pointers_82575 - Init func ptrs.
* @hw: pointer to the HW structure
*
- * The only function explicitly called by the api module to initialize
- * all function pointers and parameters.
+ * Called to initialize all function pointers and parameters.
*/
void
e1000_init_function_pointers_82575(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82575");
- hw->func.init_mac_params = e1000_init_mac_params_82575;
- hw->func.init_nvm_params = e1000_init_nvm_params_82575;
- hw->func.init_phy_params = e1000_init_phy_params_82575;
+ hw->mac.ops.init_params = e1000_init_mac_params_82575;
+ hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
+ hw->phy.ops.init_params = e1000_init_phy_params_82575;
}
/*
* e1000_acquire_phy_82575 - Acquire rights to access PHY
* @hw: pointer to the HW structure
*
- * Acquire access rights to the correct PHY. This is a
- * function pointer entry point called by the api module.
+ * Acquire access rights to the correct PHY.
*/
static s32
e1000_acquire_phy_82575(struct e1000_hw *hw)
@@ -361,8 +341,7 @@ e1000_acquire_phy_82575(struct e1000_hw *hw)
* e1000_release_phy_82575 - Release rights to access PHY
* @hw: pointer to the HW structure
*
- * A wrapper to release access rights to the correct PHY. This is a
- * function pointer entry point called by the api module.
+ * A wrapper to release access rights to the correct PHY.
*/
static void
e1000_release_phy_82575(struct e1000_hw *hw)
@@ -488,10 +467,10 @@ e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data)
}
/*
- * e1000_get_phy_id_82575 - Retreive PHY addr and id
+ * e1000_get_phy_id_82575 - Retrieve PHY addr and id
* @hw: pointer to the HW structure
*
- * Retreives the PHY address and ID for both PHY's which do and do not use
+ * Retrieves the PHY address and ID for both PHY's which do and do not use
* sgmi interface.
*/
static s32
@@ -560,7 +539,7 @@ out:
static s32
e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575");
@@ -571,15 +550,18 @@ e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
DEBUGOUT("Soft resetting SGMII attached PHY...\n");
+ if (!(hw->phy.ops.write_reg))
+ goto out;
+
/*
* SFP documentation requires the following to configure the SPF module
* to work on SGMII. No further documentation is given.
*/
- ret_val = e1000_write_phy_reg(hw, 0x1B, 0x8084);
+ ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
if (ret_val)
goto out;
- ret_val = e1000_phy_commit(hw);
+ ret_val = hw->phy.ops.commit(hw);
out:
return (ret_val);
@@ -588,7 +570,7 @@ out:
/*
* e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
* @hw: pointer to the HW structure
- * @active: TRUE to enable LPLU, FALSE to disable
+ * @active: true to enable LPLU, false to disable
*
* Sets the LPLU D0 state according to the active flag. When
* activating LPLU this function also disables smart speed
@@ -602,36 +584,39 @@ static s32
e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
u16 data;
DEBUGFUNC("e1000_set_d0_lplu_state_82575");
- ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
+ if (!(hw->phy.ops.read_reg))
+ goto out;
+
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (active) {
data |= IGP02E1000_PM_D0_LPLU;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else {
data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
/*
@@ -641,27 +626,27 @@ e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
@@ -677,7 +662,7 @@ out:
* e1000_acquire_nvm_82575 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
- * Acquire the necessary semaphores for exclussive access to the EEPROM.
+ * Acquire the necessary semaphores for exclusive access to the EEPROM.
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
@@ -844,7 +829,7 @@ e1000_get_cfg_done_82575(struct e1000_hw *hw)
* @duplex: stores the current duplex
*
* This is a wrapper function, if using the serial gigabit media independent
- * interface, use pcs to retreive the link speed and duplex information.
+ * interface, use PCS to retrieve the link speed and duplex information.
* Otherwise, use the generic function to get the link speed and duplex info.
*/
static s32
@@ -898,7 +883,7 @@ e1000_check_for_link_82575(struct e1000_hw *hw)
* @speed: stores the current speed
* @duplex: stores the current duplex
*
- * Using the physical coding sub-layer (PCS), retreive the current speed and
+ * Using the physical coding sub-layer (PCS), retrieve the current speed and
* duplex, then store the values in the pointers provided.
*/
static s32
@@ -911,7 +896,7 @@ 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;
+ mac->serdes_has_link = false;
*speed = 0;
*duplex = 0;
@@ -928,7 +913,7 @@ e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
* can be determined by checking for both link up and link sync ok
*/
if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
- mac->serdes_has_link = TRUE;
+ mac->serdes_has_link = true;
/* Detect and store PCS speed */
if (pcs & E1000_PCS_LSTS_SPEED_1000) {
@@ -946,25 +931,147 @@ e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
*duplex = HALF_DUPLEX;
}
}
+
return (E1000_SUCCESS);
}
/*
- * e1000_rar_set_82575 - Set receive address register
+ * e1000_init_rx_addrs_82575 - Initialize receive address's
* @hw: pointer to the HW structure
- * @addr: pointer to the receive address
- * @index: receive address array register
+ * @rar_count: receive address registers
*
- * Sets the receive address array register at index to the address passed
- * in by addr.
+ * Setups the receive address registers by setting the base receive address
+ * register to the devices MAC address and clearing all the other receive
+ * address registers to 0.
*/
static void
-e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
+e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
{
- DEBUGFUNC("e1000_rar_set_82575");
+ u32 i;
+ u8 addr[6] = {0, 0, 0, 0, 0, 0};
+ /*
+ * This function is essentially the same as that of
+ * e1000_init_rx_addrs_generic. However it also takes care
+ * of the special case where the register offset of the
+ * second set of RARs begins elsewhere. This is implicitly taken care by
+ * function e1000_rar_set_generic.
+ */
+
+ DEBUGFUNC("e1000_init_rx_addrs_82575");
+
+ /* Setup the receive address */
+ DEBUGOUT("Programming MAC Address into RAR[0]\n");
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
- if (index < E1000_RAR_ENTRIES_82575) {
- e1000_rar_set_generic(hw, addr, index);
+ /* Zero out the other (rar_entry_count - 1) receive addresses */
+ DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count - 1);
+ for (i = 1; i < rar_count; i++) {
+ hw->mac.ops.rar_set(hw, addr, i);
+ }
+}
+
+/*
+ * e1000_update_mc_addr_list_82575 - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ * @rar_used_count: the first RAR register free to program
+ * @rar_count: total number of supported Receive Address Registers
+ *
+ * Updates the Receive Address Registers and Multicast Table Array.
+ * The caller must have a packed mc_addr_list of multicast addresses.
+ * The parameter rar_count will usually be hw->mac.rar_entry_count
+ * unless there are workarounds that change this.
+ */
+static void
+e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count)
+{
+ u32 hash_value;
+ u32 i;
+ u8 addr[6] = {0, 0, 0, 0, 0, 0};
+ /*
+ * This function is essentially the same as that of
+ * e1000_update_mc_addr_list_generic. However it also takes care
+ * of the special case where the register offset of the
+ * second set of RARs begins elsewhere. This is implicitly taken care by
+ * function e1000_rar_set_generic.
+ */
+
+ DEBUGFUNC("e1000_update_mc_addr_list_82575");
+
+ /*
+ * Load the first set of multicast addresses into the exact
+ * filters (RAR). If there are not enough to fill the RAR
+ * array, clear the filters.
+ */
+ for (i = rar_used_count; i < rar_count; i++) {
+ if (mc_addr_count) {
+ e1000_rar_set_generic(hw, mc_addr_list, i);
+ mc_addr_count--;
+ mc_addr_list += ETH_ADDR_LEN;
+ } else {
+ e1000_rar_set_generic(hw, addr, i);
+ }
+ }
+
+ /* Clear the old settings from the MTA */
+ DEBUGOUT("Clearing MTA\n");
+ for (i = 0; i < hw->mac.mta_reg_count; i++) {
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
+ E1000_WRITE_FLUSH(hw);
+ }
+
+ /* Load any remaining multicast addresses into the hash table. */
+ for (; mc_addr_count > 0; mc_addr_count--) {
+ hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
+ DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
+ hw->mac.ops.mta_set(hw, hash_value);
+ mc_addr_list += ETH_ADDR_LEN;
+ }
+}
+
+/*
+ * e1000_shutdown_fiber_serdes_link_82575 - Remove link during power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of fiber serdes shut down optics and PCS on driver unload
+ * when management pass thru is not enabled.
+ */
+void
+e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
+{
+ u32 reg;
+ u16 eeprom_data = 0;
+
+ if (hw->mac.type != e1000_82576 ||
+ (hw->phy.media_type != e1000_media_type_fiber &&
+ hw->phy.media_type != e1000_media_type_internal_serdes))
+ return;
+
+ if (hw->bus.func == 0)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+
+ /*
+ * If APM is not enabled in the EEPROM and management interface is
+ * not enabled, then power down.
+ */
+ if (!(eeprom_data & E1000_NVM_APME_82575) &&
+ !e1000_enable_mng_pass_thru(hw)) {
+ /* Disable PCS to turn off link */
+ reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
+ reg &= ~E1000_PCS_CFG_PCS_EN;
+ E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg);
+
+ /* shutdown the laser */
+ reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+ reg |= E1000_CTRL_EXT_SDP7_DATA;
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
+
+ /* flush the write to verfiy completion */
+ E1000_WRITE_FLUSH(hw);
+ msec_delay(1);
}
}
@@ -972,8 +1079,7 @@ e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
* e1000_reset_hw_82575 - Reset hardware
* @hw: pointer to the HW structure
*
- * This resets the hardware into a known state. This is a
- * function pointer entry point called by the api module.
+ * This resets the hardware into a known state.
*/
static s32
e1000_reset_hw_82575(struct e1000_hw *hw)
@@ -1053,17 +1159,17 @@ e1000_init_hw_82575(struct e1000_hw *hw)
/* Disabling VLAN filtering */
DEBUGOUT("Initializing the IEEE VLAN\n");
- e1000_clear_vfta(hw);
+ mac->ops.clear_vfta(hw);
/* Setup the receive address */
- e1000_init_rx_addrs_generic(hw, rar_count);
+ e1000_init_rx_addrs_82575(hw, rar_count);
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Setup link and flow control */
- ret_val = e1000_setup_link(hw);
+ ret_val = mac->ops.setup_link(hw);
/*
* Clear all of the statistics registers (clear on read). It is
@@ -1132,7 +1238,7 @@ e1000_setup_copper_link_82575(struct e1000_hw *hw)
* depending on user settings.
*/
DEBUGOUT("Forcing Speed and Duplex\n");
- ret_val = e1000_phy_force_speed_duplex(hw);
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
DEBUGOUT("Error Forcing Speed and Duplex\n");
goto out;
@@ -1197,6 +1303,13 @@ e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_CTRL_SWDPIN1;
E1000_WRITE_REG(hw, E1000_CTRL, reg);
+ /* Power on phy for 82576 fiber adapters */
+ if (hw->mac.type == e1000_82576) {
+ reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_SDP7_DATA;
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
+ }
+
/* Set switch control to serdes energy detect */
reg = E1000_READ_REG(hw, E1000_CONNSW);
reg |= E1000_CONNSW_ENRGSRC;
@@ -1229,12 +1342,55 @@ e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
DEBUGOUT1("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
}
+
+ if (hw->mac.type == e1000_82576) {
+ reg |= E1000_PCS_LCTL_FORCE_FCTRL;
+ e1000_force_mac_fc_generic(hw);
+ }
+
E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
return (E1000_SUCCESS);
}
/*
+ * e1000_valid_led_default_82575 - Verify a valid default LED config
+ * @hw: pointer to the HW structure
+ * @data: pointer to the NVM (EEPROM)
+ *
+ * Read the EEPROM for the current default LED configuration. If the
+ * LED configuration is not valid, set to a valid LED configuration.
+ */
+static s32
+e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
+{
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_valid_led_default_82575");
+
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ goto out;
+ }
+
+ if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
+ switch (hw->phy.media_type) {
+ case e1000_media_type_fiber:
+ case e1000_media_type_internal_serdes:
+ *data = ID_LED_DEFAULT_82575_SERDES;
+ break;
+ case e1000_media_type_copper:
+ default:
+ *data = ID_LED_DEFAULT;
+ break;
+ }
+ }
+out:
+ return (ret_val);
+}
+
+/*
* e1000_configure_pcs_link_82575 - Configure PCS link
* @hw: pointer to the HW structure
*
@@ -1271,7 +1427,7 @@ e1000_configure_pcs_link_82575(struct e1000_hw *hw)
*/
reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
} else {
- /* Set PCS regiseter for forced speed */
+ /* Set PCS register for forced speed */
/* Turn off bits for full duplex, speed, and autoneg */
reg &= ~(E1000_PCS_LCTL_FSV_1000 |
@@ -1312,22 +1468,14 @@ out:
static bool
e1000_sgmii_active_82575(struct e1000_hw *hw)
{
- struct e1000_dev_spec_82575 *dev_spec;
- bool ret_val;
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
DEBUGFUNC("e1000_sgmii_active_82575");
- if (hw->mac.type != e1000_82575) {
- ret_val = FALSE;
- goto out;
- }
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
- ret_val = dev_spec->sgmii_active;
+ if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
+ return (false);
-out:
- return (ret_val);
+ return (dev_spec->sgmii_active);
}
/*
@@ -1345,25 +1493,38 @@ e1000_reset_init_script_82575(struct e1000_hw *hw)
if (hw->mac.type == e1000_82575) {
DEBUGOUT("Running reset init script for 82575\n");
/* SerDes configuration via SERDESCTRL */
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x1B, 0x23);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x23, 0x15);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL,
+ 0x00, 0x0C);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL,
+ 0x01, 0x78);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL,
+ 0x1B, 0x23);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL,
+ 0x23, 0x15);
/* CCM configuration via CCMCTL register */
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x14, 0x00);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x10, 0x00);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL,
+ 0x14, 0x00);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL,
+ 0x10, 0x00);
/* PCIe lanes configuration */
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x00, 0xEC);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x61, 0xDF);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x34, 0x05);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x2F, 0x81);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL,
+ 0x00, 0xEC);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL,
+ 0x61, 0xDF);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL,
+ 0x34, 0x05);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_GIOCTL,
+ 0x2F, 0x81);
/* PCIe PLL Configuration */
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x02, 0x47);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x14, 0x00);
- (void) e1000_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x10, 0x00);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL,
+ 0x02, 0x47);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL,
+ 0x14, 0x00);
+ (void) e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL,
+ 0x10, 0x00);
}
return (E1000_SUCCESS);
@@ -1395,8 +1556,14 @@ e1000_read_mac_addr_82575(struct e1000_hw *hw)
static void
e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
{
+ struct e1000_phy_info *phy = &hw->phy;
+ struct e1000_mac_info *mac = &hw->mac;
+
+ if (!(phy->ops.check_reset_block))
+ return;
+
/* If the management interface is not enabled, then power down */
- if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw)))
+ if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
e1000_power_down_phy_copper(hw);
}
@@ -1464,3 +1631,80 @@ e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
if (hw->phy.media_type == e1000_media_type_internal_serdes)
(void) E1000_READ_REG(hw, E1000_SCVPC);
}
+
+/*
+ * e1000_rx_fifo_flush_82575 - Clean rx fifo after RX enable
+ * @hw: pointer to the HW structure
+ *
+ * After rx enable if managability is enabled then there is likely some
+ * bad data at the start of the fifo and possibly in the DMA fifo. This
+ * function clears the fifos and flushes any packets that came in as rx was
+ * being enabled.
+ */
+void
+e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
+{
+ u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
+ int i, ms_wait;
+
+ DEBUGFUNC("e1000_rx_fifo_workaround_82575");
+ if (hw->mac.type != e1000_82575 ||
+ !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
+ return;
+
+ /* Disable all RX queues */
+ for (i = 0; i < 4; i++) {
+ rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
+ E1000_WRITE_REG(hw, E1000_RXDCTL(i),
+ rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
+ }
+ /* Poll all queues to verify they have shut down */
+ for (ms_wait = 0; ms_wait < 10; ms_wait++) {
+ msec_delay(1);
+ rx_enabled = 0;
+ for (i = 0; i < 4; i++)
+ rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
+ if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
+ break;
+ }
+
+ if (ms_wait == 10)
+ DEBUGOUT("Queue disable timed out after 10ms\n");
+
+ /*
+ * Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
+ * incoming packets are rejected. Set enable and wait 2ms so that
+ * any packet that was coming in as RCTL.EN was set is flushed
+ */
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
+
+ rlpml = E1000_READ_REG(hw, E1000_RLPML);
+ E1000_WRITE_REG(hw, E1000_RLPML, 0);
+
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+ temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
+ temp_rctl |= E1000_RCTL_LPE;
+
+ E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
+ E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
+ E1000_WRITE_FLUSH(hw);
+ msec_delay(2);
+
+ /*
+ * Enable RX queues that were previously enabled and restore our
+ * previous state
+ */
+ for (i = 0; i < 4; i++)
+ E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+ E1000_WRITE_FLUSH(hw);
+
+ E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
+ /* Flush receive errors generated by workaround */
+ (void) E1000_READ_REG(hw, E1000_ROC);
+ (void) E1000_READ_REG(hw, E1000_RNBC);
+ (void) E1000_READ_REG(hw, E1000_MPC);
+}
diff --git a/usr/src/uts/common/io/igb/igb_82575.h b/usr/src/uts/common/io/igb/igb_82575.h
index 9bad509dcc..06bb5d064e 100644
--- a/usr/src/uts/common/io/igb/igb_82575.h
+++ b/usr/src/uts/common/io/igb/igb_82575.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,28 +22,36 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.33 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.57 v2008-10-7 */
#ifndef _IGB_82575_H
#define _IGB_82575_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
+#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
+ (ID_LED_DEF1_DEF2 << 8) | \
+ (ID_LED_DEF1_DEF2 << 4) | \
+ (ID_LED_OFF1_ON2))
+
/*
* Receive Address Register Count
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* These entries are also used for MAC-based filtering.
*/
-#define E1000_RAR_ENTRIES_82575 16
+/*
+ * For 82576, there are an additional set of RARs that begin at an offset
+ * separate from the first set of RARs.
+ */
+#define E1000_RAR_ENTRIES_82575 16
+#define E1000_RAR_ENTRIES_82576 24
#ifdef E1000_BIT_FIELDS
struct e1000_adv_data_desc {
@@ -129,10 +137,17 @@ struct e1000_adv_context_desc {
#define E1000_TX_SEQNUM_WB_ENABLE 0x2
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
+#define E1000_MRQC_ENABLE_VMDQ 0x00000003
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
+#define E1000_VMRCTL_MIRROR_PORT_SHIFT 8
+#define E1000_VMRCTL_MIRROR_DSTPORT_MASK (7 << E1000_VMRCTL_MIRROR_PORT_SHIFT)
+#define E1000_VMRCTL_POOL_MIRROR_ENABLE (1 << 0)
+#define E1000_VMRCTL_UPLINK_MIRROR_ENABLE (1 << 1)
+#define E1000_VMRCTL_DOWNLINK_MIRROR_ENABLE (1 << 2)
+
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
@@ -174,11 +189,14 @@ union e1000_adv_rx_desc {
} read;
struct {
struct {
- struct {
- /* RSS type, Packet type */
- u16 pkt_info;
- /* Split Header, header buffer length */
- u16 hdr_info;
+ union {
+ u32 data;
+ struct {
+ /* RSS type, Packet type */
+ u16 pkt_info;
+ /* Split Header, header buffer length */
+ u16 hdr_info;
+ } hs_rss;
} lo_dword;
union {
u32 rss; /* RSS Hash */
@@ -202,7 +220,7 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
#define E1000_RXDADV_SPLITHEADER_EN 0x00001000
#define E1000_RXDADV_SPH 0x8000
-#define E1000_RXDADV_HBO 0x00800000
+#define E1000_RXDADV_ERR_HBO 0x00800000
/* RSS Hash results */
#define E1000_RXDADV_RSSTYPE_NONE 0x00000000
@@ -227,6 +245,27 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
#define E1000_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
+#define E1000_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
+#define E1000_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
+#define E1000_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */
+#define E1000_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */
+#define E1000_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */
+#define E1000_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */
+
+/* LinkSec results */
+/* Security Processing bit Indication */
+#define E1000_RXDADV_LNKSEC_STATUS_SECP 0x00020000
+#define E1000_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000
+#define E1000_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000
+#define E1000_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000
+#define E1000_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000
+
+#define E1000_RXDADV_IPSEC_STATUS_SECP 0x00020000
+#define E1000_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000
+#define E1000_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000
+#define E1000_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
+#define E1000_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED 0x18000000
+
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
@@ -246,16 +285,15 @@ union e1000_adv_tx_desc {
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
-#define E1000_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
-#define E1000_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit in RDMA DDP hdr */
#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
@@ -320,6 +358,128 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
+/* Additional DCA related definitions, note change in position of CPUID */
+#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
+#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
+#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
+#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+
+/* Additional interrupt register bit definitions */
+#define E1000_ICR_LSECPNS 0x00000020 /* PN threshold - server */
+#define E1000_IMS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
+#define E1000_ICS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
+
+/* ETQF register bit definitions */
+#define E1000_ETQF_FILTER_ENABLE (1 << 26)
+#define E1000_ETQF_IMM_INT (1 << 29)
+#define E1000_ETQF_1588 (1 << 30)
+#define E1000_ETQF_QUEUE_ENABLE (1 << 31)
+/*
+ * ETQF filter list: one static filter per filter consumer. This is
+ * to avoid filter collisions later. Add new filters
+ * here!!
+ *
+ * Current filters:
+ * EAPOL 802.1x (0x888e): Filter 0
+ */
+#define E1000_ETQF_FILTER_EAPOL 0
+
+#define E1000_NVM_APME_82575 0x0400
+#define MAX_NUM_VFS 8
+
+#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
+#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
+#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
+
+/* Easy defines for setting default pool, would normally be left a zero */
+#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
+#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
+
+/* Other useful VMD_CTL register defines */
+#define E1000_VT_CTL_IGNORE_MAC (1 << 28)
+#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29)
+#define E1000_VT_CTL_VM_REPL_EN (1 << 30)
+
+/* Per VM Offload register setup */
+#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
+#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
+#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
+#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
+#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
+
+#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */
+#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */
+#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
+#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
+#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
+#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */
+
+#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
+#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
+#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
+
+#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
+
+/*
+ * If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF. The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+/* Messages below or'd with this are the ACK */
+#define E1000_VT_MSGTYPE_ACK 0xF0000000
+/* Messages below or'd with this are the NACK */
+#define E1000_VT_MSGTYPE_NACK 0xFF000000
+#define E1000_VT_MSGINFO_SHIFT 16
+/* bits 23:16 are used for exra info for certain messages */
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
+
+#define E1000_VF_MSGTYPE_REQ_MAC 1 /* VF needs to know its MAC */
+#define E1000_VF_MSGTYPE_VFLR 2 /* VF notifies VFLR to PF */
+#define E1000_VF_SET_MULTICAST 3 /* VF requests PF to set MC addr */
+#define E1000_VF_SET_VLAN 4 /* VF requests PF to set VLAN */
+
+/*
+ * Add 100h to all PF msgs, leaves room for up to 255 discrete message types
+ * from VF to PF - way more than we'll ever need
+ */
+/* PF notifies global reset imminent to VF */
+#define E1000_PF_MSGTYPE_RESET (1 + 0x100)
+/* PF notifies VF of LSC... VF will see extra msg info for status */
+#define E1000_PF_MSGTYPE_LSC (2 + 0x100)
+
+#define E1000_PF_MSG_LSCDOWN (1 << E1000_VT_MSGINFO_SHIFT)
+#define E1000_PF_MSG_LSCUP (2 << E1000_VT_MSGINFO_SHIFT)
+
+#define ALL_QUEUES 0xFFFF
+
+s32 e1000_send_mail_to_pf_vf(struct e1000_hw *hw, u32 *msg,
+ s16 size);
+s32 e1000_receive_mail_from_pf_vf(struct e1000_hw *hw,
+ u32 *msg, s16 size);
+s32 e1000_send_mail_to_vf(struct e1000_hw *hw, u32 *msg,
+ u32 vf_number, s16 size);
+s32 e1000_receive_mail_from_vf(struct e1000_hw *hw, u32 *msg,
+ u32 vf_number, s16 size);
+void e1000_vmdq_loopback_enable_vf(struct e1000_hw *hw);
+void e1000_vmdq_loopback_disable_vf(struct e1000_hw *hw);
+void e1000_vmdq_replication_enable_vf(struct e1000_hw *hw, u32 enables);
+void e1000_vmdq_replication_disable_vf(struct e1000_hw *hw);
+void e1000_vmdq_enable_replication_mode_vf(struct e1000_hw *hw);
+void e1000_vmdq_broadcast_replication_enable_vf(struct e1000_hw *hw,
+ u32 enables);
+void e1000_vmdq_multicast_replication_enable_vf(struct e1000_hw *hw,
+ u32 enables);
+void e1000_vmdq_broadcast_replication_disable_vf(struct e1000_hw *hw,
+ u32 disables);
+void e1000_vmdq_multicast_replication_disable_vf(struct e1000_hw *hw,
+ u32 disables);
+bool e1000_check_for_pf_ack_vf(struct e1000_hw *hw);
+bool e1000_check_for_pf_mail_vf(struct e1000_hw *hw, u32*);
+
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/io/igb/igb_api.c b/usr/src/uts/common/io/igb/igb_api.c
index 3b2fc40a1b..76d8f60e77 100644
--- a/usr/src/uts/common/io/igb/igb_api.c
+++ b/usr/src/uts/common/io/igb/igb_api.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,18 +22,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.73 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.107 v2008-10-7 */
#include "igb_api.h"
-#include "igb_mac.h"
-#include "igb_nvm.h"
-#include "igb_phy.h"
/*
* e1000_init_mac_params - Initialize MAC function pointers
@@ -47,8 +42,8 @@ e1000_init_mac_params(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
- if (hw->func.init_mac_params) {
- ret_val = hw->func.init_mac_params(hw);
+ if (hw->mac.ops.init_params) {
+ ret_val = hw->mac.ops.init_params(hw);
if (ret_val) {
DEBUGOUT("MAC Initialization Error\n");
goto out;
@@ -74,8 +69,8 @@ e1000_init_nvm_params(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
- if (hw->func.init_nvm_params) {
- ret_val = hw->func.init_nvm_params(hw);
+ if (hw->nvm.ops.init_params) {
+ ret_val = hw->nvm.ops.init_params(hw);
if (ret_val) {
DEBUGOUT("NVM Initialization Error\n");
goto out;
@@ -101,8 +96,8 @@ e1000_init_phy_params(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
- if (hw->func.init_phy_params) {
- ret_val = hw->func.init_phy_params(hw);
+ if (hw->phy.ops.init_params) {
+ ret_val = hw->phy.ops.init_params(hw);
if (ret_val) {
DEBUGOUT("PHY Initialization Error\n");
goto out;
@@ -139,6 +134,12 @@ e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82575GB_QUAD_COPPER:
mac->type = e1000_82575;
break;
+ case E1000_DEV_ID_82576:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ mac->type = e1000_82576;
+ break;
default:
/* Should never have loaded on this device */
ret_val = -E1000_ERR_MAC_INIT;
@@ -151,10 +152,10 @@ e1000_set_mac_type(struct e1000_hw *hw)
/*
* e1000_setup_init_funcs - Initializes function pointers
* @hw: pointer to the HW structure
- * @init_device: TRUE will initialize the rest of the function pointers
- * getting the device ready for use. FALSE will only set
+ * @init_device: true will initialize the rest of the function pointers
+ * getting the device ready for use. false will only set
* MAC type and the function pointers for the other init
- * functions. Passing FALSE will not generate any hardware
+ * functions. Passing false will not generate any hardware
* reads or writes.
*
* This function must be called by a driver in order to use the rest
@@ -179,18 +180,12 @@ e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
}
/*
- * Init some generic function pointers that are currently all pointing
- * to generic implementations. We do this first allowing a driver
- * module to override it afterwards.
+ * Init function pointers to generic implementations. We do this first
+ * allowing a driver module to override it afterward.
*/
- hw->func.config_collision_dist = e1000_config_collision_dist_generic;
- hw->func.rar_set = e1000_rar_set_generic;
- hw->func.validate_mdi_setting = e1000_validate_mdi_setting_generic;
- hw->func.mng_host_if_write = e1000_mng_host_if_write_generic;
- hw->func.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;
- hw->func.mng_enable_host_if = e1000_mng_enable_host_if_generic;
- hw->func.wait_autoneg = e1000_wait_autoneg_generic;
- hw->func.reload_nvm = e1000_reload_nvm_generic;
+ e1000_init_mac_ops_generic(hw);
+ e1000_init_phy_ops_generic(hw);
+ e1000_init_nvm_ops_generic(hw);
/*
* Set up the init function pointers. These are functions within the
@@ -199,6 +194,7 @@ e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
*/
switch (hw->mac.type) {
case e1000_82575:
+ case e1000_82576:
e1000_init_function_pointers_82575(hw);
break;
default:
@@ -231,32 +227,18 @@ out:
}
/*
- * e1000_remove_device - Free device specific structure
- * @hw: pointer to the HW structure
- *
- * If a device specific structure was allocated, this function will
- * free it. This is a function pointer entry point called by drivers.
- */
-void
-e1000_remove_device(struct e1000_hw *hw)
-{
- if (hw->func.remove_device)
- hw->func.remove_device(hw);
-}
-
-/*
* e1000_get_bus_info - Obtain bus information for adapter
* @hw: pointer to the HW structure
*
* This will obtain information about the HW bus for which the
- * adaper is attached and stores it in the hw structure. This is a
+ * adapter is attached and stores it in the hw structure. This is a
* function pointer entry point called by drivers.
*/
s32
e1000_get_bus_info(struct e1000_hw *hw)
{
- if (hw->func.get_bus_info)
- return (hw->func.get_bus_info(hw));
+ if (hw->mac.ops.get_bus_info)
+ return (hw->mac.ops.get_bus_info(hw));
return (E1000_SUCCESS);
}
@@ -271,8 +253,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
void
e1000_clear_vfta(struct e1000_hw *hw)
{
- if (hw->func.clear_vfta)
- hw->func.clear_vfta(hw);
+ if (hw->mac.ops.clear_vfta)
+ hw->mac.ops.clear_vfta(hw);
}
/*
@@ -287,8 +269,8 @@ e1000_clear_vfta(struct e1000_hw *hw)
void
e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
{
- if (hw->func.write_vfta)
- hw->func.write_vfta(hw, offset, value);
+ if (hw->mac.ops.write_vfta)
+ hw->mac.ops.write_vfta(hw, offset, value);
}
/*
@@ -310,8 +292,8 @@ void
e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
u32 mc_addr_count, u32 rar_used_count, u32 rar_count)
{
- if (hw->func.update_mc_addr_list)
- hw->func.update_mc_addr_list(hw,
+ if (hw->mac.ops.update_mc_addr_list)
+ hw->mac.ops.update_mc_addr_list(hw,
mc_addr_list,
mc_addr_count,
rar_used_count,
@@ -343,8 +325,8 @@ e1000_force_mac_fc(struct e1000_hw *hw)
s32
e1000_check_for_link(struct e1000_hw *hw)
{
- if (hw->func.check_for_link)
- return (hw->func.check_for_link(hw));
+ if (hw->mac.ops.check_for_link)
+ return (hw->mac.ops.check_for_link(hw));
return (-E1000_ERR_CONFIG);
}
@@ -359,10 +341,10 @@ e1000_check_for_link(struct e1000_hw *hw)
bool
e1000_check_mng_mode(struct e1000_hw *hw)
{
- if (hw->func.check_mng_mode)
- return (hw->func.check_mng_mode(hw));
+ if (hw->mac.ops.check_mng_mode)
+ return (hw->mac.ops.check_mng_mode(hw));
- return (FALSE);
+ return (false);
}
/*
@@ -389,8 +371,8 @@ e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length)
s32
e1000_reset_hw(struct e1000_hw *hw)
{
- if (hw->func.reset_hw)
- return (hw->func.reset_hw(hw));
+ if (hw->mac.ops.reset_hw)
+ return (hw->mac.ops.reset_hw(hw));
return (-E1000_ERR_CONFIG);
}
@@ -405,8 +387,8 @@ e1000_reset_hw(struct e1000_hw *hw)
s32
e1000_init_hw(struct e1000_hw *hw)
{
- if (hw->func.init_hw)
- return (hw->func.init_hw(hw));
+ if (hw->mac.ops.init_hw)
+ return (hw->mac.ops.init_hw(hw));
return (-E1000_ERR_CONFIG);
}
@@ -422,8 +404,8 @@ e1000_init_hw(struct e1000_hw *hw)
s32
e1000_setup_link(struct e1000_hw *hw)
{
- if (hw->func.setup_link)
- return (hw->func.setup_link(hw));
+ if (hw->mac.ops.setup_link)
+ return (hw->mac.ops.setup_link(hw));
return (-E1000_ERR_CONFIG);
}
@@ -441,8 +423,8 @@ e1000_setup_link(struct e1000_hw *hw)
s32
e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
{
- if (hw->func.get_link_up_info)
- return (hw->func.get_link_up_info(hw, speed, duplex));
+ if (hw->mac.ops.get_link_up_info)
+ return (hw->mac.ops.get_link_up_info(hw, speed, duplex));
return (-E1000_ERR_CONFIG);
}
@@ -458,8 +440,8 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex)
s32
e1000_setup_led(struct e1000_hw *hw)
{
- if (hw->func.setup_led)
- return (hw->func.setup_led(hw));
+ if (hw->mac.ops.setup_led)
+ return (hw->mac.ops.setup_led(hw));
return (E1000_SUCCESS);
}
@@ -474,8 +456,8 @@ e1000_setup_led(struct e1000_hw *hw)
s32
e1000_cleanup_led(struct e1000_hw *hw)
{
- if (hw->func.cleanup_led)
- return (hw->func.cleanup_led(hw));
+ if (hw->mac.ops.cleanup_led)
+ return (hw->mac.ops.cleanup_led(hw));
return (E1000_SUCCESS);
}
@@ -491,8 +473,8 @@ e1000_cleanup_led(struct e1000_hw *hw)
s32
e1000_blink_led(struct e1000_hw *hw)
{
- if (hw->func.blink_led)
- return (hw->func.blink_led(hw));
+ if (hw->mac.ops.blink_led)
+ return (hw->mac.ops.blink_led(hw));
return (E1000_SUCCESS);
}
@@ -507,8 +489,8 @@ e1000_blink_led(struct e1000_hw *hw)
s32
e1000_led_on(struct e1000_hw *hw)
{
- if (hw->func.led_on)
- return (hw->func.led_on(hw));
+ if (hw->mac.ops.led_on)
+ return (hw->mac.ops.led_on(hw));
return (E1000_SUCCESS);
}
@@ -523,8 +505,8 @@ e1000_led_on(struct e1000_hw *hw)
s32
e1000_led_off(struct e1000_hw *hw)
{
- if (hw->func.led_off)
- return (hw->func.led_off(hw));
+ if (hw->mac.ops.led_off)
+ return (hw->mac.ops.led_off(hw));
return (E1000_SUCCESS);
}
@@ -579,8 +561,8 @@ e1000_disable_pcie_master(struct e1000_hw *hw)
void
e1000_config_collision_dist(struct e1000_hw *hw)
{
- if (hw->func.config_collision_dist)
- hw->func.config_collision_dist(hw);
+ if (hw->mac.ops.config_collision_dist)
+ hw->mac.ops.config_collision_dist(hw);
}
/*
@@ -594,8 +576,8 @@ e1000_config_collision_dist(struct e1000_hw *hw)
void
e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
{
- if (hw->func.rar_set)
- hw->func.rar_set(hw, addr, index);
+ if (hw->mac.ops.rar_set)
+ hw->mac.ops.rar_set(hw, addr, index);
}
/*
@@ -607,8 +589,8 @@ e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
s32
e1000_validate_mdi_setting(struct e1000_hw *hw)
{
- if (hw->func.validate_mdi_setting)
- return (hw->func.validate_mdi_setting(hw));
+ if (hw->mac.ops.validate_mdi_setting)
+ return (hw->mac.ops.validate_mdi_setting(hw));
return (E1000_SUCCESS);
}
@@ -624,8 +606,8 @@ e1000_validate_mdi_setting(struct e1000_hw *hw)
void
e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
{
- if (hw->func.mta_set)
- hw->func.mta_set(hw, hash_value);
+ if (hw->mac.ops.mta_set)
+ hw->mac.ops.mta_set(hw, hash_value);
}
/*
@@ -674,9 +656,9 @@ s32
e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum)
{
- if (hw->func.mng_host_if_write)
- return (hw->func.mng_host_if_write(hw, buffer, length, offset,
- sum));
+ if (hw->mac.ops.mng_host_if_write)
+ return (hw->mac.ops.mng_host_if_write(hw, buffer, length,
+ offset, sum));
return (E1000_NOT_IMPLEMENTED);
}
@@ -692,8 +674,8 @@ s32
e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr)
{
- if (hw->func.mng_write_cmd_header)
- return (hw->func.mng_write_cmd_header(hw, hdr));
+ if (hw->mac.ops.mng_write_cmd_header)
+ return (hw->mac.ops.mng_write_cmd_header(hw, hdr));
return (E1000_NOT_IMPLEMENTED);
}
@@ -704,15 +686,15 @@ e1000_mng_write_cmd_header(struct e1000_hw *hw,
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
- * This function checks whether the HOST IF is enabled for command operaton
+ * This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
*/
s32
e1000_mng_enable_host_if(struct e1000_hw *hw)
{
- if (hw->func.mng_enable_host_if)
- return (hw->func.mng_enable_host_if(hw));
+ if (hw->mac.ops.mng_enable_host_if)
+ return (hw->mac.ops.mng_enable_host_if(hw));
return (E1000_NOT_IMPLEMENTED);
}
@@ -727,8 +709,8 @@ e1000_mng_enable_host_if(struct e1000_hw *hw)
s32
e1000_wait_autoneg(struct e1000_hw *hw)
{
- if (hw->func.wait_autoneg)
- return (hw->func.wait_autoneg(hw));
+ if (hw->mac.ops.wait_autoneg)
+ return (hw->mac.ops.wait_autoneg(hw));
return (E1000_SUCCESS);
}
@@ -743,8 +725,8 @@ e1000_wait_autoneg(struct e1000_hw *hw)
s32
e1000_check_reset_block(struct e1000_hw *hw)
{
- if (hw->func.check_reset_block)
- return (hw->func.check_reset_block(hw));
+ if (hw->phy.ops.check_reset_block)
+ return (hw->phy.ops.check_reset_block(hw));
return (E1000_SUCCESS);
}
@@ -761,8 +743,8 @@ e1000_check_reset_block(struct e1000_hw *hw)
s32
e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
{
- if (hw->func.read_phy_reg)
- return (hw->func.read_phy_reg(hw, offset, data));
+ if (hw->phy.ops.read_reg)
+ return (hw->phy.ops.read_reg(hw, offset, data));
return (E1000_SUCCESS);
}
@@ -779,8 +761,38 @@ e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
s32
e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
{
- if (hw->func.write_phy_reg)
- return (hw->func.write_phy_reg(hw, offset, data));
+ if (hw->phy.ops.write_reg)
+ return (hw->phy.ops.write_reg(hw, offset, data));
+
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_release_phy - Generic release PHY
+ * @hw: pointer to the HW structure
+ *
+ * Return if silicon family does not require a semaphore when accessing the
+ * PHY.
+ */
+void
+e1000_release_phy(struct e1000_hw *hw)
+{
+ if (hw->phy.ops.release)
+ hw->phy.ops.release(hw);
+}
+
+/*
+ * e1000_acquire_phy - Generic acquire PHY
+ * @hw: pointer to the HW structure
+ *
+ * Return success if silicon family does not require a semaphore when
+ * accessing the PHY.
+ */
+s32
+e1000_acquire_phy(struct e1000_hw *hw)
+{
+ if (hw->phy.ops.acquire)
+ return (hw->phy.ops.acquire(hw));
return (E1000_SUCCESS);
}
@@ -828,8 +840,8 @@ e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
s32
e1000_get_cable_length(struct e1000_hw *hw)
{
- if (hw->func.get_cable_length)
- return (hw->func.get_cable_length(hw));
+ if (hw->phy.ops.get_cable_length)
+ return (hw->phy.ops.get_cable_length(hw));
return (E1000_SUCCESS);
}
@@ -845,8 +857,8 @@ e1000_get_cable_length(struct e1000_hw *hw)
s32
e1000_get_phy_info(struct e1000_hw *hw)
{
- if (hw->func.get_phy_info)
- return (hw->func.get_phy_info(hw));
+ if (hw->phy.ops.get_info)
+ return (hw->phy.ops.get_info(hw));
return (E1000_SUCCESS);
}
@@ -861,8 +873,8 @@ e1000_get_phy_info(struct e1000_hw *hw)
s32
e1000_phy_hw_reset(struct e1000_hw *hw)
{
- if (hw->func.reset_phy)
- return (hw->func.reset_phy(hw));
+ if (hw->phy.ops.reset)
+ return (hw->phy.ops.reset(hw));
return (E1000_SUCCESS);
}
@@ -877,14 +889,14 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
s32
e1000_phy_commit(struct e1000_hw *hw)
{
- if (hw->func.commit_phy)
- return (hw->func.commit_phy(hw));
+ if (hw->phy.ops.commit)
+ return (hw->phy.ops.commit(hw));
return (E1000_SUCCESS);
}
/*
- * e1000_set_d3_lplu_state - Sets low power link up state for D0
+ * e1000_set_d0_lplu_state - Sets low power link up state for D0
* @hw: pointer to the HW structure
* @active: boolean used to enable/disable lplu
*
@@ -900,8 +912,8 @@ e1000_phy_commit(struct e1000_hw *hw)
s32
e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
{
- if (hw->func.set_d0_lplu_state)
- return (hw->func.set_d0_lplu_state(hw, active));
+ if (hw->phy.ops.set_d0_lplu_state)
+ return (hw->phy.ops.set_d0_lplu_state(hw, active));
return (E1000_SUCCESS);
}
@@ -923,8 +935,8 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
s32
e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
{
- if (hw->func.set_d3_lplu_state)
- return (hw->func.set_d3_lplu_state(hw, active));
+ if (hw->phy.ops.set_d3_lplu_state)
+ return (hw->phy.ops.set_d3_lplu_state(hw, active));
return (E1000_SUCCESS);
}
@@ -940,8 +952,8 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active)
s32
e1000_read_mac_addr(struct e1000_hw *hw)
{
- if (hw->func.read_mac_addr)
- return (hw->func.read_mac_addr(hw));
+ if (hw->mac.ops.read_mac_addr)
+ return (hw->mac.ops.read_mac_addr(hw));
return (e1000_read_mac_addr_generic(hw));
}
@@ -972,8 +984,8 @@ e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num)
s32
e1000_validate_nvm_checksum(struct e1000_hw *hw)
{
- if (hw->func.validate_nvm)
- return (hw->func.validate_nvm(hw));
+ if (hw->nvm.ops.validate)
+ return (hw->nvm.ops.validate(hw));
return (-E1000_ERR_CONFIG);
}
@@ -988,8 +1000,8 @@ e1000_validate_nvm_checksum(struct e1000_hw *hw)
s32
e1000_update_nvm_checksum(struct e1000_hw *hw)
{
- if (hw->func.update_nvm)
- return (hw->func.update_nvm(hw));
+ if (hw->nvm.ops.update)
+ return (hw->nvm.ops.update(hw));
return (-E1000_ERR_CONFIG);
}
@@ -1004,8 +1016,8 @@ e1000_update_nvm_checksum(struct e1000_hw *hw)
void
e1000_reload_nvm(struct e1000_hw *hw)
{
- if (hw->func.reload_nvm)
- hw->func.reload_nvm(hw);
+ if (hw->nvm.ops.reload)
+ hw->nvm.ops.reload(hw);
}
/*
@@ -1021,8 +1033,8 @@ e1000_reload_nvm(struct e1000_hw *hw)
s32
e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
- if (hw->func.read_nvm)
- return (hw->func.read_nvm(hw, offset, words, data));
+ if (hw->nvm.ops.read)
+ return (hw->nvm.ops.read(hw, offset, words, data));
return (-E1000_ERR_CONFIG);
}
@@ -1040,8 +1052,8 @@ e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
s32
e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
- if (hw->func.write_nvm)
- return (hw->func.write_nvm(hw, offset, words, data));
+ if (hw->nvm.ops.write)
+ return (hw->nvm.ops.write(hw, offset, words, data));
return (E1000_SUCCESS);
}
@@ -1072,8 +1084,8 @@ e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data)
void
e1000_power_up_phy(struct e1000_hw *hw)
{
- if (hw->func.power_up_phy)
- hw->func.power_up_phy(hw);
+ if (hw->phy.ops.power_up)
+ hw->phy.ops.power_up(hw);
(void) e1000_setup_link(hw);
}
@@ -1088,6 +1100,19 @@ e1000_power_up_phy(struct e1000_hw *hw)
void
e1000_power_down_phy(struct e1000_hw *hw)
{
- if (hw->func.power_down_phy)
- hw->func.power_down_phy(hw);
+ if (hw->phy.ops.power_down)
+ hw->phy.ops.power_down(hw);
+}
+
+/*
+ * e1000_shutdown_fiber_serdes_link - Remove link during power down
+ * @hw: pointer to the HW structure
+ *
+ * Shutdown the optics and PCS on driver unload.
+ */
+void
+e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw)
+{
+ if (hw->mac.ops.shutdown_serdes)
+ hw->mac.ops.shutdown_serdes(hw);
}
diff --git a/usr/src/uts/common/io/igb/igb_api.h b/usr/src/uts/common/io/igb/igb_api.h
index 2052d08242..f6a28170bb 100644
--- a/usr/src/uts/common/io/igb/igb_api.h
+++ b/usr/src/uts/common/io/igb/igb_api.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.39 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.50 v2008-10-7 */
#ifndef _IGB_API_H
#define _IGB_API_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,13 +38,15 @@ extern "C" {
#include "igb_hw.h"
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
+extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw);
+extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
+extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw);
s32 e1000_init_nvm_params(struct e1000_hw *hw);
s32 e1000_init_phy_params(struct e1000_hw *hw);
-void e1000_remove_device(struct e1000_hw *hw);
s32 e1000_get_bus_info(struct e1000_hw *hw);
void e1000_clear_vfta(struct e1000_hw *hw);
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
@@ -79,6 +79,8 @@ s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
s32 e1000_get_phy_info(struct e1000_hw *hw);
+void e1000_release_phy(struct e1000_hw *hw);
+s32 e1000_acquire_phy(struct e1000_hw *hw);
s32 e1000_phy_hw_reset(struct e1000_hw *hw);
s32 e1000_phy_commit(struct e1000_hw *hw);
void e1000_power_up_phy(struct e1000_hw *hw);
@@ -96,7 +98,6 @@ s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
bool e1000_check_mng_mode(struct e1000_hw *hw);
-bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
s32 e1000_mng_host_if_write(struct e1000_hw *hw,
@@ -105,14 +106,6 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw,
u8 *buffer, u16 length);
-#ifndef FIFO_WORKAROUND
-s32 e1000_fifo_workaround_82547(struct e1000_hw *hw, u16 length);
-void e1000_update_tx_fifo_head_82547(struct e1000_hw *hw, u32 length);
-void e1000_set_ttl_workaround_state_82541(struct e1000_hw *hw, bool state);
-bool e1000_ttl_workaround_enabled_82541(struct e1000_hw *hw);
-s32 e1000_igp_ttl_workaround_82547(struct e1000_hw *hw);
-#endif
-
/*
* TBI_ACCEPT macro definition:
@@ -133,11 +126,11 @@ s32 e1000_igp_ttl_workaround_82547(struct e1000_hw *hw);
* Typical use:
* ...
* if (TBI_ACCEPT) {
- * accept_frame = TRUE;
+ * accept_frame = true;
* e1000_tbi_adjust_stats(adapter, MacAddress);
* frame_length--;
* } else {
- * accept_frame = FALSE;
+ * accept_frame = false;
* }
* ...
*/
diff --git a/usr/src/uts/common/io/igb/igb_buf.c b/usr/src/uts/common/io/igb/igb_buf.c
index dd1aca689c..06d795e3f4 100644
--- a/usr/src/uts/common/io/igb/igb_buf.c
+++ b/usr/src/uts/common/io/igb/igb_buf.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "igb_sw.h"
static int igb_alloc_tbd_ring(igb_tx_ring_t *);
@@ -807,14 +805,9 @@ igb_alloc_rcb_lists(igb_rx_ring_t *rx_ring)
rcb->free_rtn.free_arg = (char *)rcb;
rcb->mp = desballoc((unsigned char *)
- rx_buf->address - IPHDR_ALIGN_ROOM,
- rx_buf->size + IPHDR_ALIGN_ROOM,
+ rx_buf->address,
+ rx_buf->size,
0, &rcb->free_rtn);
-
- if (rcb->mp != NULL) {
- rcb->mp->b_rptr += IPHDR_ALIGN_ROOM;
- rcb->mp->b_wptr += IPHDR_ALIGN_ROOM;
- }
}
return (IGB_SUCCESS);
diff --git a/usr/src/uts/common/io/igb/igb_debug.c b/usr/src/uts/common/io/igb/igb_debug.c
index 021656cbaa..889ff34997 100644
--- a/usr/src/uts/common/io/igb/igb_debug.c
+++ b/usr/src/uts/common/io/igb/igb_debug.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "igb_sw.h"
#include "igb_debug.h"
@@ -259,13 +257,14 @@ pci_dump(void *arg)
pci_config_get16(handle, offset + PCIE_LINKSTS));
/* MSI-X Memory Space */
- if (ddi_dev_regsize(igb->dip, 4, &mem_size) != DDI_SUCCESS) {
+ if (ddi_dev_regsize(igb->dip, IGB_ADAPTER_MSIXTAB, &mem_size) !=
+ DDI_SUCCESS) {
igb_log(igb, "ddi_dev_regsize() failed");
return;
}
- if ((ddi_regs_map_setup(igb->dip, 4, (caddr_t *)&base, 0, mem_size,
- &igb_regs_acc_attr, &acc_hdl)) != DDI_SUCCESS) {
+ if ((ddi_regs_map_setup(igb->dip, IGB_ADAPTER_MSIXTAB, (caddr_t *)&base,
+ 0, mem_size, &igb_regs_acc_attr, &acc_hdl)) != DDI_SUCCESS) {
igb_log(igb, "ddi_regs_map_setup() failed");
return;
}
diff --git a/usr/src/uts/common/io/igb/igb_defines.h b/usr/src/uts/common/io/igb/igb_defines.h
index d1c43fa5d6..5e2942628c 100644
--- a/usr/src/uts/common/io/igb/igb_defines.h
+++ b/usr/src/uts/common/io/igb/igb_defines.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.54 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.79 v2008-10-7 */
#ifndef _IGB_DEFINES_H
#define _IGB_DEFINES_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -61,25 +59,21 @@ extern "C" {
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_IGNORE_TCO_BM 0x00000800 /* Ignore WakeOn TCO packets */
-#define E1000_WUFC_FLX0_BM 0x00001000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1_BM 0x00002000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2_BM 0x00004000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3_BM 0x00008000 /* Flexible Filter 3 Enable */
#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-/* Mask for all wakeup filters */
-#define E1000_WUFC_ALL_FILTERS_BM 0x0000F0FF
-/* Offset to the Flexible Filters bits */
-#define E1000_WUFC_FLX_OFFSET_BM 12
-/* Mask for the 4 flexible filters */
-#define E1000_WUFC_FLX_FILTERS_BM 0x0000F000
+#define E1000_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
+#define E1000_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+/*
+ * For 82576 to utilize Extended filter masks in addition to
+ * existing (filter) masks
+ */
+#define E1000_WUFC_EXT_FLX_FILTERS 0x00300000 /* Ext. FLX filter mask */
/* Wake Up Status */
#define E1000_WUS_LNKC E1000_WUFC_LNKC
@@ -90,11 +84,6 @@ extern "C" {
#define E1000_WUS_ARP E1000_WUFC_ARP
#define E1000_WUS_IPV4 E1000_WUFC_IPV4
#define E1000_WUS_IPV6 E1000_WUFC_IPV6
-#define E1000_WUS_FLX0_BM E1000_WUFC_FLX0_BM
-#define E1000_WUS_FLX1_BM E1000_WUFC_FLX1_BM
-#define E1000_WUS_FLX2_BM E1000_WUFC_FLX2_BM
-#define E1000_WUS_FLX3_BM E1000_WUFC_FLX3_BM
-#define E1000_WUS_FLX_FILTERS_BM E1000_WUFC_FLX_FILTERS_BM
#define E1000_WUS_FLX0 E1000_WUFC_FLX0
#define E1000_WUS_FLX1 E1000_WUFC_FLX1
#define E1000_WUS_FLX2 E1000_WUFC_FLX2
@@ -106,6 +95,10 @@ extern "C" {
/* Four Flexible Filters are supported */
#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+/* Two Extended Flexible Filters are supported (82576) */
+#define E1000_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
+#define E1000_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */
+#define E1000_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */
/* Each Flexible Filter is at most 128 (0x80) bytes in length */
#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
@@ -121,11 +114,11 @@ extern "C" {
#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
/* Reserved (bits 4,5) in >= 82575 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Definable Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Definable Pin 5 */
#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
-#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Definable Pin 6 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
/* SDP 4/5 (bits 8,9) are reserved in >= 82575 */
#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
@@ -134,6 +127,8 @@ extern "C" {
#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
+/* Physical Func Reset Done Indication */
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
@@ -150,7 +145,7 @@ extern "C" {
#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-#define E1000_CTRL_EXT_CANC 0x04000000 /* Interrupt delay cancellation */
+#define E1000_CTRL_EXT_CANC 0x04000000 /* Int delay cancellation */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
/* IAME enable bit (27) was removed in >= 82575 */
/* Interrupt acknowledge Auto-mask */
@@ -175,13 +170,18 @@ extern "C" {
#define E1000_I2CCMD_ERROR 0x80000000
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
#define E1000_I2CCMD_PHY_TIMEOUT 200
+#define E1000_IVAR_VALID 0x80
+#define E1000_GPIE_NSICR 0x00000001
+#define E1000_GPIE_MSIX_MODE 0x00000010
+#define E1000_GPIE_EIAME 0x40000000
+#define E1000_GPIE_PBA 0x80000000
-/* Receive Decriptor bit definitions */
+/* Receive Descriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
@@ -265,7 +265,7 @@ extern "C" {
#define E1000_MANC_EN_MNG2HOST 0x00200000
/* Enable IP address filtering */
#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000
-#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable cksum filtering */
+#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
@@ -350,6 +350,7 @@ extern "C" {
#define E1000_SWFW_EEP_SM 0x1
#define E1000_SWFW_PHY0_SM 0x2
#define E1000_SWFW_PHY1_SM 0x4
+#define E1000_SWFW_CSR_SM 0x8
/* FACTPS Definitions */
#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */
@@ -392,8 +393,7 @@ extern "C" {
#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-/* Initiate an interrupt to manageability engine */
-#define E1000_CTRL_SW2FW_INT 0x02000000
+#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to ME */
#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */
/*
@@ -410,6 +410,7 @@ extern "C" {
#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA
#define E1000_CONNSW_ENRGSRC 0x4
+#define E1000_PCS_CFG_PCS_EN 8
#define E1000_PCS_LCTL_FLV_LINK_UP 1
#define E1000_PCS_LCTL_FSV_10 0
#define E1000_PCS_LCTL_FSV_100 2
@@ -418,6 +419,7 @@ extern "C" {
#define E1000_PCS_LCTL_FSD 0x10
#define E1000_PCS_LCTL_FORCE_LINK 0x20
#define E1000_PCS_LCTL_LOW_LINK_LATCH 0x40
+#define E1000_PCS_LCTL_FORCE_FCTRL 0x80
#define E1000_PCS_LCTL_AN_ENABLE 0x10000
#define E1000_PCS_LCTL_AN_RESTART 0x20000
#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
@@ -457,8 +459,7 @@ extern "C" {
#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
/* Change in Dock/Undock state. Clear on write '0'. */
#define E1000_STATUS_DOCK_CI 0x00000800
-/* Status of Master requests. */
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */
#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
@@ -476,7 +477,7 @@ extern "C" {
#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
-/* Constants used to intrepret the masked PCI-X bus speed. */
+/* Constants used to interpret the masked PCI-X bus speed. */
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
@@ -617,6 +618,7 @@ extern "C" {
#define E1000_RFCTL_EXTEN 0x00008000
#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
+#define E1000_RFCTL_LEF 0x00040000
/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD 15
@@ -663,9 +665,10 @@ extern "C" {
#define E1000_KABGTXD_BGSQLBIAS 0x00050000
/* PBA constants */
-#define E1000_PBA_8K 0x0008 /* 8KB */
-#define E1000_PBA_12K 0x000C /* 12KB */
-#define E1000_PBA_16K 0x0010 /* 16KB */
+#define E1000_PBA_6K 0x0006 /* 6KB */
+#define E1000_PBA_8K 0x0008 /* 8KB */
+#define E1000_PBA_12K 0x000C /* 12KB */
+#define E1000_PBA_16K 0x0010 /* 16KB */
#define E1000_PBA_20K 0x0014
#define E1000_PBA_22K 0x0016
#define E1000_PBA_24K 0x0018
@@ -700,6 +703,7 @@ extern "C" {
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */
#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
@@ -713,28 +717,19 @@ extern "C" {
#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
-/* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
-/* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
-/* host arb read buffer parity error */
-#define E1000_ICR_HOST_ARB_PAR 0x00400000
+#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* Q0 Rx desc FIFO parity error */
+#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* Q0 Tx desc FIFO parity error */
+#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity err */
#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
-/* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
+#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* Q1 Rx desc FIFO parity error */
+#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* Q1 Tx desc FIFO parity error */
#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
/* FW changed the status of DISSW bit in the FWSM */
#define E1000_ICR_DSW 0x00000020
/* LAN connected device generates an interrupt */
#define E1000_ICR_PHYINT 0x00001000
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
-#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
-#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
-#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
-#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
-#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */
+#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
+#define E1000_ICR_EPRST 0x00100000 /* ME hardware reset occurs */
/* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
@@ -783,6 +778,7 @@ extern "C" {
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
@@ -812,12 +808,8 @@ extern "C" {
#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1
#define E1000_IMS_DSW E1000_ICR_DSW
#define E1000_IMS_PHYINT E1000_ICR_PHYINT
+#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
#define E1000_IMS_EPRST E1000_ICR_EPRST
-#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */
-#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */
-#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */
-#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */
-#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */
/* Extended Interrupt Mask Set */
#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */
@@ -863,6 +855,7 @@ extern "C" {
/* queue 1 Tx descriptor FIFO parity error */
#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1
#define E1000_ICS_DSW E1000_ICR_DSW
+#define E1000_ICS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
#define E1000_ICS_PHYINT E1000_ICR_PHYINT
#define E1000_ICS_EPRST E1000_ICR_EPRST
@@ -1075,7 +1068,7 @@ extern "C" {
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
-#define PHY_STATUS 0x01 /* Status Regiser */
+#define PHY_STATUS 0x01 /* Status Register */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
@@ -1120,8 +1113,7 @@ extern "C" {
#define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */
#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */
-/* Offset to data in NVM read/write registers */
-#define E1000_NVM_RW_REG_DATA 16
+#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START 1 /* Start operation */
#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
@@ -1133,8 +1125,7 @@ extern "C" {
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004
#define NVM_VERSION 0x0005
-/* For SERDES output amplitude adjustment. */
-#define NVM_SERDES_AMPLITUDE 0x0006
+#define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */
#define NVM_PHY_CLASS_WORD 0x0007
#define NVM_INIT_CONTROL1_REG 0x000A
#define NVM_INIT_CONTROL2_REG 0x000F
@@ -1181,7 +1172,7 @@ extern "C" {
#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */
#define NVM_ERASE_OPCODE_MICROWIRE 0x7 /* NVM erase opcode */
#define NVM_EWEN_OPCODE_MICROWIRE 0x13 /* NVM erase/write enable */
-#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erast/write disable */
+#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erase/write disable */
/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
@@ -1263,8 +1254,7 @@ extern "C" {
#define IFE_E_PHY_ID 0x02A80330
#define IFE_PLUS_E_PHY_ID 0x02A80320
#define IFE_C_E_PHY_ID 0x02A80310
-#define BME1000_E_PHY_ID 0x01410CB0
-#define BME1000_E_PHY_ID_R2 0x01410CB1
+#define IGP04E1000_E_PHY_ID 0x02A80391
#define M88_VENDOR 0x0141
/* M88E1000 Specific Registers */
@@ -1371,9 +1361,6 @@ extern "C" {
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00
-/* BME1000 PHY Specific Control Register */
-#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
-
/*
* Bits...
* 15-5: page
@@ -1465,9 +1452,29 @@ extern "C" {
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640
-#ifndef UNREFERENCED_PARAMETER
-#define UNREFERENCED_PARAMETER(_p)
-#endif
+/* LinkSec register fields */
+#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000
+#define E1000_LSECTXCAP_SUM_SHIFT 16
+#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000
+#define E1000_LSECRXCAP_SUM_SHIFT 16
+
+#define E1000_LSECTXCTRL_EN_MASK 0x00000003
+#define E1000_LSECTXCTRL_DISABLE 0x0
+#define E1000_LSECTXCTRL_AUTH 0x1
+#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2
+#define E1000_LSECTXCTRL_AISCI 0x00000020
+#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
+#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8
+
+#define E1000_LSECRXCTRL_EN_MASK 0x0000000C
+#define E1000_LSECRXCTRL_EN_SHIFT 2
+#define E1000_LSECRXCTRL_DISABLE 0x0
+#define E1000_LSECRXCTRL_CHECK 0x1
+#define E1000_LSECRXCTRL_STRICT 0x2
+#define E1000_LSECRXCTRL_DROP 0x3
+#define E1000_LSECRXCTRL_PLSH 0x00000040
+#define E1000_LSECRXCTRL_RP 0x00000080
+#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/io/igb/igb_hw.h b/usr/src/uts/common/io/igb/igb_hw.h
index 04c410d7d1..3b6dc8dd2d 100644
--- a/usr/src/uts/common/io/igb/igb_hw.h
+++ b/usr/src/uts/common/io/igb/igb_hw.h
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,15 +22,11 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.357 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.398 v2008-10-7 */
#ifndef _IGB_HW_H
#define _IGB_HW_H
@@ -43,6 +41,10 @@ extern "C" {
struct e1000_hw;
+#define E1000_DEV_ID_82576 0x10C9
+#define E1000_DEV_ID_82576_FIBER 0x10E6
+#define E1000_DEV_ID_82576_SERDES 0x10E7
+#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
@@ -56,38 +58,39 @@ struct e1000_hw;
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
-typedef enum {
+enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
+ e1000_82576,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
-} e1000_mac_type;
+};
-typedef enum {
+enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
-} e1000_media_type;
+};
-typedef enum {
+enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
-} e1000_nvm_type;
+};
-typedef enum {
+enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
e1000_nvm_override_microwire_small,
e1000_nvm_override_microwire_large
-} e1000_nvm_override;
+};
-typedef enum {
+enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
@@ -96,18 +99,18 @@ typedef enum {
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
- e1000_phy_bm
-} e1000_phy_type;
+ e1000_phy_vf
+};
-typedef enum {
+enum e1000_bus_type {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
-} e1000_bus_type;
+};
-typedef enum {
+enum e1000_bus_speed {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
@@ -117,9 +120,9 @@ typedef enum {
e1000_bus_speed_2500,
e1000_bus_speed_5000,
e1000_bus_speed_reserved
-} e1000_bus_speed;
+};
-typedef enum {
+enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
@@ -128,59 +131,72 @@ typedef enum {
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
-} e1000_bus_width;
+};
-typedef enum {
+enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
-} e1000_1000t_rx_status;
+};
-typedef enum {
+enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
-} e1000_rev_polarity;
+};
-typedef enum {
+enum e1000_fc_mode {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
-} e1000_fc_type;
+};
+
+enum e1000_ms_type {
+ e1000_ms_hw_default = 0,
+ e1000_ms_force_master,
+ e1000_ms_force_slave,
+ e1000_ms_auto
+};
+
+enum e1000_smart_speed {
+ e1000_smart_speed_default = 0,
+ e1000_smart_speed_on,
+ e1000_smart_speed_off
+};
/* Receive Descriptor */
struct e1000_rx_desc {
- u64 buffer_addr; /* Address of the descriptor's data buffer */
- u16 length; /* Length of data DMAed into data buffer */
- u16 csum; /* Packet checksum */
+ __le64 buffer_addr; /* Address of the descriptor's data buffer */
+ __le16 length; /* Length of data DMAed into data buffer */
+ __le16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
- u16 special;
+ __le16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
- u64 buffer_addr;
- u64 reserved;
+ __le64 buffer_addr;
+ __le64 reserved;
} read;
struct {
struct {
- u32 mrq; /* Multiple Rx Queues */
+ __le32 mrq; /* Multiple Rx Queues */
union {
- u32 rss; /* RSS Hash */
+ __le32 rss; /* RSS Hash */
struct {
- u16 ip_id; /* IP id */
- u16 csum; /* Packet Checksum */
+ __le16 ip_id; /* IP id */
+ __le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
- u32 status_error; /* ext status/error */
- u16 length;
- u16 vlan; /* VLAN tag */
+ __le32 status_error; /* ext status/error */
+ __le16 length;
+ __le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
@@ -190,49 +206,49 @@ union e1000_rx_desc_extended {
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
- u64 buffer_addr[MAX_PS_BUFFERS];
+ __le64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
- u32 mrq; /* Multiple Rx Queues */
+ __le32 mrq; /* Multiple Rx Queues */
union {
- u32 rss; /* RSS Hash */
+ __le32 rss; /* RSS Hash */
struct {
- u16 ip_id; /* IP id */
- u16 csum; /* Packet Checksum */
+ __le16 ip_id; /* IP id */
+ __le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
- u32 status_error; /* ext status/error */
- u16 length0; /* length of buffer 0 */
- u16 vlan; /* VLAN tag */
+ __le32 status_error; /* ext status/error */
+ __le16 length0; /* length of buffer 0 */
+ __le16 vlan; /* VLAN tag */
} middle;
struct {
- u16 header_status;
- u16 length[3]; /* length of buffers 1-3 */
+ __le16 header_status;
+ __le16 length[3]; /* length of buffers 1-3 */
} upper;
- u64 reserved;
+ __le64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
- u64 buffer_addr; /* Address of the descriptor's data buffer */
+ __le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
- u32 data;
+ __le32 data;
struct {
- u16 length; /* Data buffer length */
+ __le16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
- u32 data;
+ __le32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
- u16 special;
+ __le16 special;
} fields;
} upper;
};
@@ -240,49 +256,49 @@ struct e1000_tx_desc {
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
- u32 ip_config;
+ __le32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
- u16 ipcse; /* IP checksum end */
+ __le16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
- u32 tcp_config;
+ __le32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
- u16 tucse; /* TCP checksum end */
+ __le16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
- u32 cmd_and_length;
+ __le32 cmd_and_length;
union {
- u32 data;
+ __le32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
- u16 mss; /* Maximum segment size */
+ __le16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
- u64 buffer_addr; /* Address of the descriptor's buffer address */
+ __le64 buffer_addr; /* Address of the descriptor's buffer address */
union {
- u32 data;
+ __le32 data;
struct {
- u16 length; /* Data buffer length */
+ __le16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
- u32 data;
+ __le32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
- u16 special;
+ __le16 special;
} fields;
} upper;
};
@@ -364,6 +380,7 @@ struct e1000_hw_stats {
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
+ u64 doosync;
};
struct e1000_phy_stats {
@@ -416,9 +433,9 @@ struct e1000_host_mng_command_info {
#include "igb_nvm.h"
#include "igb_manage.h"
-struct e1000_functions {
+struct e1000_mac_operations {
/* Function pointers for the MAC. */
- s32 (*init_mac_params)(struct e1000_hw *);
+ s32 (*init_params)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *hw);
@@ -430,9 +447,9 @@ struct e1000_functions {
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
- void (*remove_device)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
+ void (*shutdown_serdes)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
@@ -447,43 +464,46 @@ struct e1000_functions {
struct e1000_host_mng_command_header *);
s32 (*mng_enable_host_if)(struct e1000_hw *);
s32 (*wait_autoneg)(struct e1000_hw *);
+};
- /* Function pointers for the PHY. */
- s32 (*init_phy_params)(struct e1000_hw *);
- s32 (*acquire_phy)(struct e1000_hw *);
+struct e1000_phy_operations {
+ s32 (*init_params)(struct e1000_hw *);
+ s32 (*acquire)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
- s32 (*commit_phy)(struct e1000_hw *);
+ s32 (*commit)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
- s32 (*get_phy_info)(struct e1000_hw *);
- s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
- void (*release_phy)(struct e1000_hw *);
- s32 (*reset_phy)(struct e1000_hw *);
+ s32 (*get_info)(struct e1000_hw *);
+ s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
+ void (*release)(struct e1000_hw *);
+ s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
- void (*power_up_phy)(struct e1000_hw *);
- void (*power_down_phy)(struct e1000_hw *);
-
- /* Function pointers for the NVM. */
- s32 (*init_nvm_params)(struct e1000_hw *);
- s32 (*acquire_nvm)(struct e1000_hw *);
- s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
- void (*release_nvm)(struct e1000_hw *);
- void (*reload_nvm)(struct e1000_hw *);
- s32 (*update_nvm)(struct e1000_hw *);
+ s32 (*write_reg)(struct e1000_hw *, u32, u16);
+ void (*power_up)(struct e1000_hw *);
+ void (*power_down)(struct e1000_hw *);
+};
+
+struct e1000_nvm_operations {
+ s32 (*init_params)(struct e1000_hw *);
+ s32 (*acquire)(struct e1000_hw *);
+ s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
+ void (*release)(struct e1000_hw *);
+ void (*reload)(struct e1000_hw *);
+ s32 (*update)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
- s32 (*validate_nvm)(struct e1000_hw *);
- s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+ s32 (*validate)(struct e1000_hw *);
+ s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
+ struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
- e1000_mac_type type;
+ enum e1000_mac_type type;
u32 collision_delta;
u32 ledctl_default;
@@ -508,32 +528,29 @@ struct e1000_mac_info {
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
- bool disable_av;
- bool disable_hw_init_bits;
bool get_link_status;
- bool ifs_params_forced;
bool in_ifs_mode;
- bool report_tx_early;
bool serdes_has_link;
bool tx_pkt_filtering;
};
struct e1000_phy_info {
- e1000_phy_type type;
+ struct e1000_phy_operations ops;
+ enum e1000_phy_type type;
- e1000_1000t_rx_status local_rx;
- e1000_1000t_rx_status remote_rx;
- e1000_ms_type ms_type;
- e1000_ms_type original_ms_type;
- e1000_rev_polarity cable_polarity;
- e1000_smart_speed smart_speed;
+ enum e1000_1000t_rx_status local_rx;
+ enum e1000_1000t_rx_status remote_rx;
+ enum e1000_ms_type ms_type;
+ enum e1000_ms_type original_ms_type;
+ enum e1000_rev_polarity cable_polarity;
+ enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
- e1000_media_type media_type;
+ enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
@@ -552,8 +569,9 @@ struct e1000_phy_info {
};
struct e1000_nvm_info {
- e1000_nvm_type type;
- e1000_nvm_override override;
+ struct e1000_nvm_operations ops;
+ enum e1000_nvm_type type;
+ enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
@@ -566,11 +584,9 @@ struct e1000_nvm_info {
};
struct e1000_bus_info {
- e1000_bus_type type;
- e1000_bus_speed speed;
- e1000_bus_width width;
-
- u32 snoop;
+ enum e1000_bus_type type;
+ enum e1000_bus_speed speed;
+ enum e1000_bus_width width;
u16 func;
u16 pci_cmd_word;
@@ -582,19 +598,25 @@ struct e1000_fc_info {
u16 pause_time; /* Flow control pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
- e1000_fc_type type; /* Type of flow control */
- e1000_fc_type original_type;
+ enum e1000_fc_mode current_mode; /* FC mode in effect */
+ enum e1000_fc_mode requested_mode; /* FC mode requested by caller */
+};
+
+struct e1000_dev_spec_82575 {
+ bool sgmii_active;
+};
+
+struct e1000_dev_spec_vf {
+ u32 vf_number;
};
struct e1000_hw {
void *back;
- void *dev_spec;
u8 *hw_addr;
u8 *flash_address;
unsigned long io_base;
- struct e1000_functions func;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
@@ -602,7 +624,10 @@ struct e1000_hw {
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
- u32 dev_spec_size;
+ union {
+ struct e1000_dev_spec_82575 _82575;
+ struct e1000_dev_spec_vf vf;
+ } dev_spec;
u16 device_id;
u16 subsystem_vendor_id;
@@ -612,17 +637,12 @@ struct e1000_hw {
u8 revision_id;
};
+#include "igb_82575.h"
+
/* These functions must be implemented by drivers */
-void e1000_pci_clear_mwi(struct e1000_hw *hw);
-void e1000_pci_set_mwi(struct e1000_hw *hw);
-s32 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size);
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
-void e1000_free_dev_spec_struct(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
void e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
-void e1000_rar_clear(struct e1000_hw *hw, uint32_t);
-void e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *, uint32_t,
- uint32_t, uint8_t);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/io/igb/igb_mac.c b/usr/src/uts/common/io/igb/igb_mac.c
index 7705de0672..1854c657fc 100644
--- a/usr/src/uts/common/io/igb/igb_mac.c
+++ b/usr/src/uts/common/io/igb/igb_mac.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,31 +22,154 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.62 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.92 v2008-10-7 */
#include "igb_api.h"
-#include "igb_mac.h"
+
+static s32 e1000_set_default_fc_generic(struct e1000_hw *hw);
+static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);
+static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);
+static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
/*
- * e1000_remove_device_generic - Free device specific structure
+ * e1000_init_mac_ops_generic - Initialize MAC function pointers
* @hw: pointer to the HW structure
*
- * If a device specific structure was allocated, this function will
- * free it.
+ * Setups up the function pointers to no-op functions
+ */
+void
+e1000_init_mac_ops_generic(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ DEBUGFUNC("e1000_init_mac_ops_generic");
+
+ /* General Setup */
+ mac->ops.init_params = e1000_null_ops_generic;
+ mac->ops.init_hw = e1000_null_ops_generic;
+ mac->ops.reset_hw = e1000_null_ops_generic;
+ mac->ops.setup_physical_interface = e1000_null_ops_generic;
+ mac->ops.get_bus_info = e1000_null_ops_generic;
+ mac->ops.read_mac_addr = e1000_read_mac_addr_generic;
+ mac->ops.config_collision_dist = e1000_config_collision_dist_generic;
+ mac->ops.clear_hw_cntrs = e1000_null_mac_generic;
+ /* LED */
+ mac->ops.cleanup_led = e1000_null_ops_generic;
+ mac->ops.setup_led = e1000_null_ops_generic;
+ mac->ops.blink_led = e1000_null_ops_generic;
+ mac->ops.led_on = e1000_null_ops_generic;
+ mac->ops.led_off = e1000_null_ops_generic;
+ /* LINK */
+ mac->ops.setup_link = e1000_null_ops_generic;
+ mac->ops.get_link_up_info = e1000_null_link_info;
+ mac->ops.check_for_link = e1000_null_ops_generic;
+ mac->ops.wait_autoneg = e1000_wait_autoneg_generic;
+ /* Management */
+ mac->ops.check_mng_mode = e1000_null_mng_mode;
+ mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic;
+ mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;
+ mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic;
+ /* VLAN, MC, etc. */
+ mac->ops.update_mc_addr_list = e1000_null_update_mc;
+ mac->ops.clear_vfta = e1000_null_mac_generic;
+ mac->ops.write_vfta = e1000_null_write_vfta;
+ mac->ops.mta_set = e1000_null_mta_set;
+ mac->ops.rar_set = e1000_rar_set_generic;
+ mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic;
+}
+
+/*
+ * e1000_null_ops_generic - No-op function, returns 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_ops_generic(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_null_ops_generic");
+ UNREFERENCED_1PARAMETER(hw);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_mac_generic - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_mac_generic(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_null_mac_generic");
+ UNREFERENCED_1PARAMETER(hw);
+}
+
+/*
+ * e1000_null_link_info - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d)
+{
+ DEBUGFUNC("e1000_null_link_info");
+ UNREFERENCED_3PARAMETER(hw, s, d);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_mng_mode - No-op function, return false
+ * @hw: pointer to the HW structure
+ */
+bool
+e1000_null_mng_mode(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_null_mng_mode");
+ UNREFERENCED_1PARAMETER(hw);
+ return (false);
+}
+
+/*
+ * e1000_null_update_mc - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c)
+{
+ DEBUGFUNC("e1000_null_update_mc");
+ UNREFERENCED_5PARAMETER(hw, h, a, b, c);
+}
+
+/*
+ * e1000_null_write_vfta - No-op function, return void
+ * @hw: pointer to the HW structure
*/
void
-e1000_remove_device_generic(struct e1000_hw *hw)
+e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b)
{
- DEBUGFUNC("e1000_remove_device_generic");
+ DEBUGFUNC("e1000_null_write_vfta");
+ UNREFERENCED_3PARAMETER(hw, a, b);
+}
- /* Freeing the dev_spec member of e1000_hw structure */
- e1000_free_dev_spec_struct(hw);
+/*
+ * e1000_null_set_mta - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_mta_set(struct e1000_hw *hw, u32 a)
+{
+ DEBUGFUNC("e1000_null_mta_set");
+ UNREFERENCED_2PARAMETER(hw, a);
+}
+
+/*
+ * e1000_null_rar_set - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a)
+{
+ DEBUGFUNC("e1000_null_rar_set");
+ UNREFERENCED_3PARAMETER(hw, h, a);
}
/*
@@ -69,12 +192,14 @@ e1000_get_bus_info_pci_generic(struct e1000_hw *hw)
/* PCI or PCI-X? */
bus->type = (status & E1000_STATUS_PCIX_MODE)
- ? e1000_bus_type_pcix : e1000_bus_type_pci;
+ ? e1000_bus_type_pcix
+ : e1000_bus_type_pci;
/* Bus speed */
if (bus->type == e1000_bus_type_pci) {
bus->speed = (status & E1000_STATUS_PCI66)
- ? e1000_bus_speed_66 : e1000_bus_speed_33;
+ ? e1000_bus_speed_66
+ : e1000_bus_speed_33;
} else {
switch (status & E1000_STATUS_PCIX_SPEED) {
case E1000_STATUS_PCIX_SPEED_66:
@@ -94,7 +219,8 @@ e1000_get_bus_info_pci_generic(struct e1000_hw *hw)
/* Bus width */
bus->width = (status & E1000_STATUS_BUS64)
- ? e1000_bus_width_64 : e1000_bus_width_32;
+ ? e1000_bus_width_64
+ : e1000_bus_width_32;
/* Which PCI(-X) function? */
e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);
@@ -133,7 +259,7 @@ e1000_get_bus_info_pcie_generic(struct e1000_hw *hw)
if (ret_val)
bus->width = e1000_bus_width_unknown;
else
- bus->width = (e1000_bus_width)((pcie_link_status &
+ bus->width = (enum e1000_bus_width)((pcie_link_status &
PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT);
e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);
@@ -205,7 +331,7 @@ e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count)
/* Setup the receive address */
DEBUGOUT("Programming MAC Address into RAR[0]\n");
- e1000_rar_set_generic(hw, hw->mac.addr, 0);
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
/* Zero out the other (rar_entry_count - 1) receive addresses */
DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);
@@ -238,7 +364,7 @@ e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_alt_mac_addr_generic");
- ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+ ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
@@ -255,7 +381,7 @@ e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
for (i = 0; i < ETH_ADDR_LEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
- ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@@ -274,7 +400,7 @@ e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
for (i = 0; i < ETH_ADDR_LEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
- e1000_rar_set(hw, hw->mac.perm_addr, 0);
+ hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
out:
return (ret_val);
@@ -307,13 +433,11 @@ e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
/* If MAC address zero, no need to set the AV bit */
- if (rar_low || rar_high) {
- if (!hw->mac.disable_av)
- rar_high |= E1000_RAH_AV;
- }
+ if (rar_low || rar_high)
+ rar_high |= E1000_RAH_AV;
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low);
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high);
+ E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);
+ E1000_WRITE_REG(hw, E1000_RAH(index), rar_high);
}
/*
@@ -383,7 +507,7 @@ e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
*/
for (i = rar_used_count; i < rar_count; i++) {
if (mc_addr_count) {
- e1000_rar_set(hw, mc_addr_list, i);
+ hw->mac.ops.rar_set(hw, mc_addr_list, i);
mc_addr_count--;
mc_addr_list += ETH_ADDR_LEN;
} else {
@@ -403,9 +527,9 @@ e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
- hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
+ hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list);
DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
- e1000_mta_set(hw, hash_value);
+ hw->mac.ops.mta_set(hw, hash_value);
mc_addr_list += ETH_ADDR_LEN;
}
}
@@ -490,8 +614,8 @@ e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
*
* In certain situations, a system BIOS may report that the PCIx maximum
* memory read byte count (MMRBC) value is higher than than the actual
- * value. We check the PCIx command regsiter with the current PCIx status
- * regsiter.
+ * value. We check the PCIx command register with the current PCIx status
+ * register.
*/
void
e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw)
@@ -612,7 +736,7 @@ e1000_check_for_copper_link_generic(struct e1000_hw *hw)
if (!link)
goto out; /* No link detected */
- mac->get_link_status = FALSE;
+ mac->get_link_status = false;
/*
* Check if there was DownShift, must be checked
@@ -643,9 +767,8 @@ e1000_check_for_copper_link_generic(struct e1000_hw *hw)
* different link partner.
*/
ret_val = e1000_config_fc_after_link_up_generic(hw);
- if (ret_val) {
+ if (ret_val)
DEBUGOUT("Error configuring flow control\n");
- }
out:
return (ret_val);
@@ -715,7 +838,7 @@ e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = TRUE;
+ mac->serdes_has_link = true;
}
out:
@@ -784,7 +907,7 @@ e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = TRUE;
+ mac->serdes_has_link = true;
} else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) {
/*
* If we force link for non-auto-negotiation switch, check
@@ -793,21 +916,42 @@ e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
*/
/* SYNCH bit and IV bit are sticky. */
usec_delay(10);
- if (E1000_RXCW_SYNCH & E1000_READ_REG(hw, E1000_RXCW)) {
+ rxcw = E1000_READ_REG(hw, E1000_RXCW);
+ if (rxcw & E1000_RXCW_SYNCH) {
if (!(rxcw & E1000_RXCW_IV)) {
- mac->serdes_has_link = TRUE;
- DEBUGOUT("SERDES: Link is up.\n");
+ mac->serdes_has_link = true;
+ DEBUGOUT("SERDES: Link up - forced.\n");
}
} else {
- mac->serdes_has_link = FALSE;
- DEBUGOUT("SERDES: Link is down.\n");
+ mac->serdes_has_link = false;
+ DEBUGOUT("SERDES: Link down - force failed.\n");
}
}
if (E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW)) {
status = E1000_READ_REG(hw, E1000_STATUS);
- mac->serdes_has_link = (status & E1000_STATUS_LU)
- ? TRUE : FALSE;
+ if (status & E1000_STATUS_LU) {
+ /* SYNCH bit and IV bit are sticky, so reread rxcw. */
+ usec_delay(10);
+ rxcw = E1000_READ_REG(hw, E1000_RXCW);
+ if (rxcw & E1000_RXCW_SYNCH) {
+ if (!(rxcw & E1000_RXCW_IV)) {
+ mac->serdes_has_link = true;
+ DEBUGOUT("SERDES: Link up - autoneg "
+ "completed sucessfully.\n");
+ } else {
+ mac->serdes_has_link = false;
+ DEBUGOUT("SERDES: Link down - invalid"
+ "codewords detected in autoneg.\n");
+ }
+ } else {
+ mac->serdes_has_link = false;
+ DEBUGOUT("SERDES: Link down - no sync.\n");
+ }
+ } else {
+ mac->serdes_has_link = false;
+ DEBUGOUT("SERDES: Link down - autoneg failed\n");
+ }
}
out:
@@ -827,7 +971,6 @@ out:
s32
e1000_setup_link_generic(struct e1000_hw *hw)
{
- struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_setup_link_generic");
@@ -836,30 +979,31 @@ e1000_setup_link_generic(struct e1000_hw *hw)
* In the case of the phy reset being blocked, we already have a link.
* We do not need to set it up again.
*/
- if (e1000_check_reset_block(hw))
- goto out;
+ if (hw->phy.ops.check_reset_block)
+ if (hw->phy.ops.check_reset_block(hw))
+ goto out;
/*
- * If flow control is set to default, set flow control based on
- * the EEPROM flow control settings.
+ * If requested flow control is set to default, set flow control
+ * based on the EEPROM flow control settings.
*/
- if (hw->fc.type == e1000_fc_default) {
+ if (hw->fc.requested_mode == e1000_fc_default) {
ret_val = e1000_set_default_fc_generic(hw);
if (ret_val)
goto out;
}
/*
- * We want to save off the original Flow Control configuration just
- * in case we get disconnected and then reconnected into a different
- * hub or switch with different Flow Control capabilities.
+ * Save off the requested flow control mode for use later. Depending
+ * on the link partner's capabilities, we may or may not use this mode.
*/
- hw->fc.original_type = hw->fc.type;
+ hw->fc.current_mode = hw->fc.requested_mode;
- DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type);
+ DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
+ hw->fc.current_mode);
/* Call the necessary media_type subroutine to configure the link. */
- ret_val = func->setup_physical_interface(hw);
+ ret_val = hw->mac.ops.setup_physical_interface(hw);
if (ret_val)
goto out;
@@ -922,7 +1066,7 @@ e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
msec_delay(1);
/*
- * For these adapters, the SW defineable pin 1 is set when the optics
+ * For these adapters, the SW definable pin 1 is set when the optics
* detect a signal. If we have a signal, then poll for a "Link-Up"
* indication.
*/
@@ -999,7 +1143,7 @@ e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
* link up if we detect a signal. This will allow us to
* communicate with non-autonegotiating link partners.
*/
- ret_val = e1000_check_for_link(hw);
+ ret_val = hw->mac.ops.check_for_link(hw);
if (ret_val) {
DEBUGOUT("Error while checking for link\n");
goto out;
@@ -1047,7 +1191,7 @@ e1000_commit_fc_settings_generic(struct e1000_hw *hw)
* do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
*/
- switch (hw->fc.type) {
+ switch (hw->fc.current_mode) {
case e1000_fc_none:
/* Flow control completely disabled by a software over-ride. */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
@@ -1096,7 +1240,7 @@ out:
*
* Sets the flow control high/low threshold (watermark) registers. If
* flow control XON frame transmission is enabled, then set XON frame
- * tansmission as well.
+ * transmission as well.
*/
s32
e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
@@ -1113,7 +1257,7 @@ e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
* ability to transmit pause frames is not enabled, then these
* registers will be set to 0.
*/
- if (hw->fc.type & e1000_fc_tx_pause) {
+ if (hw->fc.current_mode & e1000_fc_tx_pause) {
/*
* We need to set up the Receive Threshold high and low water
* marks as well as (optionally) enabling the transmission of
@@ -1155,7 +1299,7 @@ e1000_set_default_fc_generic(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
- ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
@@ -1163,12 +1307,12 @@ e1000_set_default_fc_generic(struct e1000_hw *hw)
}
if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
- hw->fc.type = e1000_fc_none;
+ hw->fc.requested_mode = e1000_fc_none;
else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
NVM_WORD0F_ASM_DIR)
- hw->fc.type = e1000_fc_tx_pause;
+ hw->fc.requested_mode = e1000_fc_tx_pause;
else
- hw->fc.type = e1000_fc_full;
+ hw->fc.requested_mode = e1000_fc_full;
out:
return (ret_val);
@@ -1201,7 +1345,7 @@ e1000_force_mac_fc_generic(struct e1000_hw *hw)
* receive flow control.
*
* The "Case" statement below enables/disable flow control
- * according to the "hw->fc.type" parameter.
+ * according to the "hw->fc.current_mode" parameter.
*
* The possible values of the "fc" parameter are:
* 0: Flow control is completely disabled
@@ -1212,9 +1356,9 @@ e1000_force_mac_fc_generic(struct e1000_hw *hw)
* 3: Both Rx and Tx flow control (symmetric) is enabled.
* other: No other values should be possible at this point.
*/
- DEBUGOUT1("hw->fc.type = %u\n", hw->fc.type);
+ DEBUGOUT1("hw->fc.current_mode = %u\n", hw->fc.current_mode);
- switch (hw->fc.type) {
+ switch (hw->fc.current_mode) {
case e1000_fc_none:
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
break;
@@ -1292,10 +1436,10 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
*/
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
if (ret_val)
goto out;
@@ -1312,11 +1456,11 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
* Page Ability Register (Address 5) to determine how
* flow control was negotiated.
*/
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
@@ -1364,11 +1508,11 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
- if (hw->fc.original_type == e1000_fc_full) {
- hw->fc.type = e1000_fc_full;
+ if (hw->fc.requested_mode == e1000_fc_full) {
+ hw->fc.current_mode = e1000_fc_full;
DEBUGOUT("Flow Control = FULL.\r\n");
} else {
- hw->fc.type = e1000_fc_rx_pause;
+ hw->fc.current_mode = e1000_fc_rx_pause;
DEBUGOUT("Flow Control = "
"RX PAUSE frames only.\r\n");
}
@@ -1385,7 +1529,7 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.type = e1000_fc_tx_pause;
+ hw->fc.current_mode = e1000_fc_tx_pause;
DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n");
}
/*
@@ -1400,14 +1544,14 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc.type = e1000_fc_rx_pause;
+ hw->fc.current_mode = e1000_fc_rx_pause;
DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
} else {
/*
* Per the IEEE spec, at this point flow control
* should be disabled.
*/
- hw->fc.type = e1000_fc_none;
+ hw->fc.current_mode = e1000_fc_none;
DEBUGOUT("Flow Control = NONE.\r\n");
}
@@ -1416,14 +1560,14 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
* negotiated to HALF DUPLEX, flow control should not be
* enabled per IEEE 802.3 spec.
*/
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
+ ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
if (ret_val) {
DEBUGOUT("Error getting link speed and duplex\n");
goto out;
}
if (duplex == HALF_DUPLEX)
- hw->fc.type = e1000_fc_none;
+ hw->fc.current_mode = e1000_fc_none;
/*
* Now we call a subroutine to actually force the MAC
@@ -1441,7 +1585,7 @@ out:
}
/*
- * e1000_get_speed_and_duplex_copper_generic - Retreive current speed/duplex
+ * e1000_get_speed_and_duplex_copper_generic - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1481,7 +1625,7 @@ e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
}
/*
- * e1000_get_speed_and_duplex_fiber_generic - Retreive current speed/duplex
+ * e1000_get_speed_and_duplex_fiber_generic - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
* @duplex: stores the current duplex
@@ -1494,7 +1638,7 @@ e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
u16 *speed, u16 *duplex)
{
DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic");
- UNREFERENCED_PARAMETER(hw);
+ UNREFERENCED_1PARAMETER(hw);
*speed = SPEED_1000;
*duplex = FULL_DUPLEX;
@@ -1624,7 +1768,7 @@ e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data)
DEBUGFUNC("e1000_valid_led_default_generic");
- ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@@ -1655,7 +1799,7 @@ e1000_id_led_init_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_id_led_init_generic");
- ret_val = hw->func.valid_led_default(hw, &data);
+ ret_val = hw->nvm.ops.valid_led_default(hw, &data);
if (ret_val)
goto out;
@@ -1720,7 +1864,7 @@ e1000_setup_led_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_led_generic");
- if (hw->func.setup_led != e1000_setup_led_generic) {
+ if (hw->mac.ops.setup_led != e1000_setup_led_generic) {
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -1757,7 +1901,7 @@ e1000_cleanup_led_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_cleanup_led_generic");
- if (hw->func.cleanup_led != e1000_cleanup_led_generic) {
+ if (hw->mac.ops.cleanup_led != e1000_cleanup_led_generic) {
ret_val = -E1000_ERR_CONFIG;
goto out;
}
@@ -1772,7 +1916,7 @@ out:
* e1000_blink_led_generic - Blink LED
* @hw: pointer to the HW structure
*
- * Blink the led's which are set to be on.
+ * Blink the LEDs which are set to be on.
*/
s32
e1000_blink_led_generic(struct e1000_hw *hw)
@@ -1894,7 +2038,7 @@ e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop)
* @hw: pointer to the HW structure
*
* Returns 0 (E1000_SUCCESS) if successful, else returns -10
- * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued
+ * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
* the master requests to be disabled.
*
* Disables PCI-Express master access and verifies there are no pending
@@ -1952,15 +2096,13 @@ e1000_reset_adaptive_generic(struct e1000_hw *hw)
return;
}
- if (!mac->ifs_params_forced) {
- mac->current_ifs_val = 0;
- mac->ifs_min_val = IFS_MIN;
- mac->ifs_max_val = IFS_MAX;
- mac->ifs_step_size = IFS_STEP;
- mac->ifs_ratio = IFS_RATIO;
- }
+ mac->current_ifs_val = 0;
+ mac->ifs_min_val = IFS_MIN;
+ mac->ifs_max_val = IFS_MAX;
+ mac->ifs_step_size = IFS_STEP;
+ mac->ifs_ratio = IFS_RATIO;
- mac->in_ifs_mode = FALSE;
+ mac->in_ifs_mode = false;
E1000_WRITE_REG(hw, E1000_AIT, 0);
}
@@ -1985,7 +2127,7 @@ e1000_update_adaptive_generic(struct e1000_hw *hw)
if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
if (mac->tx_packet_delta > MIN_NUM_XMITS) {
- mac->in_ifs_mode = TRUE;
+ mac->in_ifs_mode = true;
if (mac->current_ifs_val < mac->ifs_max_val) {
if (!mac->current_ifs_val)
mac->current_ifs_val = mac->ifs_min_val;
@@ -2000,7 +2142,7 @@ e1000_update_adaptive_generic(struct e1000_hw *hw)
if (mac->in_ifs_mode &&
(mac->tx_packet_delta <= MIN_NUM_XMITS)) {
mac->current_ifs_val = 0;
- mac->in_ifs_mode = FALSE;
+ mac->in_ifs_mode = false;
E1000_WRITE_REG(hw, E1000_AIT, 0);
}
}
@@ -2010,7 +2152,7 @@ e1000_update_adaptive_generic(struct e1000_hw *hw)
* e1000_validate_mdi_setting_generic - Verify MDI/MDIx settings
* @hw: pointer to the HW structure
*
- * Verify that when not using auto-negotitation that MDI/MDIx is correctly
+ * Verify that when not using auto-negotiation that MDI/MDIx is correctly
* set, which is forced to MDI mode only.
*/
s32
diff --git a/usr/src/uts/common/io/igb/igb_mac.h b/usr/src/uts/common/io/igb/igb_mac.h
index ca893d35b1..e79eab221f 100644
--- a/usr/src/uts/common/io/igb/igb_mac.h
+++ b/usr/src/uts/common/io/igb/igb_mac.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.22 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.29 v2008-10-7 */
#ifndef _IGB_MAC_H
#define _IGB_MAC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -41,12 +39,20 @@ extern "C" {
* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
+void e1000_init_mac_ops_generic(struct e1000_hw *hw);
+void e1000_null_mac_generic(struct e1000_hw *hw);
+s32 e1000_null_ops_generic(struct e1000_hw *hw);
+s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d);
+bool e1000_null_mng_mode(struct e1000_hw *hw);
+void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c);
+void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
+void e1000_null_mta_set(struct e1000_hw *hw, u32 a);
+void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
s32 e1000_blink_led_generic(struct e1000_hw *hw);
s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_cleanup_led_generic(struct e1000_hw *hw);
-s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);
s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw);
s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw);
s32 e1000_force_mac_fc_generic(struct e1000_hw *hw);
@@ -64,13 +70,10 @@ s32 e1000_led_off_generic(struct e1000_hw *hw);
void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
-s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);
-s32 e1000_set_default_fc_generic(struct e1000_hw *hw);
s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_setup_led_generic(struct e1000_hw *hw);
s32 e1000_setup_link_generic(struct e1000_hw *hw);
-s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
@@ -85,7 +88,6 @@ void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
-void e1000_remove_device_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
void e1000_update_adaptive_generic(struct e1000_hw *hw);
diff --git a/usr/src/uts/common/io/igb/igb_main.c b/usr/src/uts/common/io/igb/igb_main.c
index ed475f0014..7a69a7bd6d 100644
--- a/usr/src/uts/common/io/igb/igb_main.c
+++ b/usr/src/uts/common/io/igb/igb_main.c
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,18 +22,14 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
-
#include "igb_sw.h"
static char ident[] = "Intel 1Gb Ethernet";
+static char igb_version[] = "igb 1.1.4";
/*
* Local function protoypes
@@ -75,7 +73,8 @@ static void igb_start_watchdog_timer(igb_t *);
static void igb_restart_watchdog_timer(igb_t *);
static void igb_stop_watchdog_timer(igb_t *);
static void igb_disable_adapter_interrupts(igb_t *);
-static void igb_enable_adapter_interrupts(igb_t *);
+static void igb_enable_adapter_interrupts_82575(igb_t *);
+static void igb_enable_adapter_interrupts_82576(igb_t *);
static boolean_t is_valid_mac_addr(uint8_t *);
static boolean_t igb_stall_check(igb_t *);
static boolean_t igb_set_loopback_mode(igb_t *, uint32_t);
@@ -91,7 +90,8 @@ static void igb_rem_intr_handlers(igb_t *);
static void igb_rem_intrs(igb_t *);
static int igb_enable_intrs(igb_t *);
static int igb_disable_intrs(igb_t *);
-static void igb_setup_adapter_msix(igb_t *);
+static void igb_setup_msix_82575(igb_t *);
+static void igb_setup_msix_82576(igb_t *);
static uint_t igb_intr_legacy(void *, void *);
static uint_t igb_intr_msi(void *, void *);
static uint_t igb_intr_rx(void *, void *);
@@ -185,6 +185,52 @@ static mac_callbacks_t igb_m_callbacks = {
};
/*
+ * Initialize capabilities of each supported adapter type
+ */
+static adapter_info_t igb_82575_cap = {
+ /* limits */
+ 4, /* maximum number of rx queues */
+ 1, /* minimum number of rx queues */
+ 4, /* default number of rx queues */
+ 4, /* maximum number of tx queues */
+ 1, /* minimum number of tx queues */
+ 4, /* default number of tx queues */
+ 65535, /* maximum interrupt throttle rate */
+ 0, /* minimum interrupt throttle rate */
+ 200, /* default interrupt throttle rate */
+
+ /* function pointers */
+ igb_enable_adapter_interrupts_82575,
+ igb_setup_msix_82575,
+
+ /* capabilities */
+ (IGB_FLAG_HAS_DCA | /* capability flags */
+ IGB_FLAG_VMDQ_POOL)
+};
+
+static adapter_info_t igb_82576_cap = {
+ /* limits */
+ 12, /* maximum number of rx queues */
+ 1, /* minimum number of rx queues */
+ 4, /* default number of rx queues */
+ 12, /* maximum number of tx queues */
+ 1, /* minimum number of tx queues */
+ 4, /* default number of tx queues */
+ 65535, /* maximum interrupt throttle rate */
+ 0, /* minimum interrupt throttle rate */
+ 200, /* default interrupt throttle rate */
+
+ /* function pointers */
+ igb_enable_adapter_interrupts_82576,
+ igb_setup_msix_82576,
+
+ /* capabilities */
+ (IGB_FLAG_HAS_DCA | /* capability flags */
+ IGB_FLAG_VMDQ_POOL |
+ IGB_FLAG_NEED_CTX_IDX)
+};
+
+/*
* Module Initialization Functions
*/
@@ -434,6 +480,7 @@ igb_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
}
igb->attach_progress |= ATTACH_PROGRESS_ENABLE_INTR;
+ igb_log(igb, "%s", igb_version);
igb->igb_state |= IGB_INITIALIZED;
return (DDI_SUCCESS);
@@ -679,11 +726,6 @@ igb_unconfigure(dev_info_t *devinfo, igb_t *igb)
}
/*
- * Free device specific structure
- */
- e1000_remove_device(&igb->hw);
-
- /*
* Free the driver data structure
*/
kmem_free(igb, sizeof (igb_t));
@@ -753,6 +795,20 @@ igb_identify_hardware(igb_t *igb)
return (IGB_FAILURE);
}
+ /*
+ * Install adapter capabilities based on mac type
+ */
+ switch (hw->mac.type) {
+ case e1000_82575:
+ igb->capab = &igb_82575_cap;
+ break;
+ case e1000_82576:
+ igb->capab = &igb_82576_cap;
+ break;
+ default:
+ return (IGB_FAILURE);
+ }
+
return (IGB_SUCCESS);
}
@@ -770,14 +826,15 @@ igb_regs_map(igb_t *igb)
/*
* First get the size of device registers to be mapped.
*/
- if (ddi_dev_regsize(devinfo, 1, &mem_size) != DDI_SUCCESS) {
+ if (ddi_dev_regsize(devinfo, IGB_ADAPTER_REGSET, &mem_size) !=
+ DDI_SUCCESS) {
return (IGB_FAILURE);
}
/*
* Call ddi_regs_map_setup() to map registers
*/
- if ((ddi_regs_map_setup(devinfo, 1,
+ if ((ddi_regs_map_setup(devinfo, IGB_ADAPTER_REGSET,
(caddr_t *)&hw->hw_addr, 0,
mem_size, &igb_regs_acc_attr,
&osdep->reg_handle)) != DDI_SUCCESS) {
@@ -881,7 +938,7 @@ igb_init_driver_settings(igb_t *igb)
}
/*
- * Initialize values of interrupt throttling rate
+ * Initialize values of interrupt throttling rates
*/
for (i = 1; i < MAX_NUM_EITR; i++)
igb->intr_throttling[i] = igb->intr_throttling[0];
@@ -1054,12 +1111,6 @@ igb_init(igb_t *igb)
}
/*
- * Set the FIFO size
- */
- pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */
- E1000_WRITE_REG(hw, E1000_PBA, pba);
-
- /*
* Setup flow control
*
* These parameters set thresholds for the adapter's generation(Tx)
@@ -1074,11 +1125,25 @@ igb_init(igb_t *igb)
* 90% of the Rx FIFO size, or the full Rx FIFO size minus one full
* frame.
*/
+ if (hw->mac.type == e1000_82575) {
+ pba = E1000_PBA_34K;
+ } else {
+ pba = E1000_PBA_64K;
+ }
+
high_water = min(((pba << 10) * 9 / 10),
((pba << 10) - igb->max_frame_size));
- hw->fc.high_water = high_water & 0xFFF8;
- hw->fc.low_water = hw->fc.high_water - 8;
+ if (hw->mac.type == e1000_82575) {
+ /* 8-byte granularity */
+ hw->fc.high_water = high_water & 0xFFF8;
+ hw->fc.low_water = hw->fc.high_water - 8;
+ } else {
+ /* 16-byte granularity */
+ hw->fc.high_water = high_water & 0xFFF0;
+ hw->fc.low_water = hw->fc.high_water - 16;
+ }
+
hw->fc.pause_time = E1000_FC_PAUSE_TIME;
hw->fc.send_xon = B_TRUE;
@@ -1235,7 +1300,7 @@ igb_chip_start(igb_t *igb)
* Setup MSI-X interrupts
*/
if (igb->intr_type == DDI_INTR_TYPE_MSIX)
- igb_setup_adapter_msix(igb);
+ igb->capab->setup_msix(igb);
/*
* Initialize unicast addresses.
@@ -1352,7 +1417,7 @@ igb_reset(igb_t *igb)
* Enable adapter interrupts
* The interrupts must be enabled after the driver state is START
*/
- igb_enable_adapter_interrupts(igb);
+ igb->capab->enable_intr(igb);
if (igb_check_acc_handle(igb->osdep.cfg_handle) != DDI_FM_OK)
goto reset_failure;
@@ -1560,7 +1625,7 @@ igb_start(igb_t *igb)
* Enable adapter interrupts
* The interrupts must be enabled after the driver state is START
*/
- igb_enable_adapter_interrupts(igb);
+ igb->capab->enable_intr(igb);
if (igb_check_acc_handle(igb->osdep.cfg_handle) != DDI_FM_OK)
goto start_failure;
@@ -1814,7 +1879,7 @@ igb_setup_rx(igb_t *igb)
igb_rx_ring_t *rx_ring;
igb_rx_group_t *rx_group;
struct e1000_hw *hw = &igb->hw;
- uint32_t reg_val;
+ uint32_t reg_val, rctl;
uint32_t ring_per_group;
int i;
@@ -1826,7 +1891,15 @@ igb_setup_rx(igb_t *igb)
* minimum threshold size to 1/2, and the receive buffer size to
* 2k.
*/
- reg_val = E1000_RCTL_EN | /* Enable Receive Unit */
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+
+ /*
+ * only used for wakeup control. This driver doesn't do wakeup
+ * but leave this here for completeness.
+ */
+ rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+
+ rctl |= E1000_RCTL_EN | /* Enable Receive Unit */
E1000_RCTL_BAM | /* Accept Broadcast Packets */
E1000_RCTL_LPE | /* Large Packet Enable bit */
(hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT) |
@@ -1834,7 +1907,7 @@ igb_setup_rx(igb_t *igb)
E1000_RCTL_SECRC | /* Strip Ethernet CRC */
E1000_RCTL_LBM_NO; /* Loopback Mode = none */
- E1000_WRITE_REG(hw, E1000_RCTL, reg_val);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl);
for (i = 0; i < igb->num_rx_groups; i++) {
rx_group = &igb->rx_groups[i];
@@ -1976,16 +2049,15 @@ igb_setup_tx_ring(igb_tx_ring_t *tx_ring)
tx_ring->tbd_free = tx_ring->ring_size;
/*
- * Note: Considering the case that the chipset is being reset,
- * and there are still some buffers held by the upper layer,
- * we should not reset the values of tcb_head, tcb_tail.
+ * Note: for the case that the chipset is being reset, we should not
+ * reset the values of tcb_head, tcb_tail. And considering there might
+ * still be some packets kept in the pending_list, we should not assert
+ * (tcb_free == free_list_size) here.
*/
if (igb->igb_state == IGB_UNKNOWN) {
tx_ring->tcb_head = 0;
tx_ring->tcb_tail = 0;
tx_ring->tcb_free = tx_ring->free_list_size;
- } else {
- ASSERT(tx_ring->tcb_free == tx_ring->free_list_size);
}
/*
@@ -2003,6 +2075,13 @@ igb_setup_tx_ring(igb_tx_ring_t *tx_ring)
tx_ring->hcksum_context.ip_hdr_len = 0;
tx_ring->hcksum_context.mac_hdr_len = 0;
tx_ring->hcksum_context.l4_proto = 0;
+
+ /*
+ * Enable TXDCTL per queue
+ */
+ reg_val = E1000_READ_REG(hw, E1000_TXDCTL(tx_ring->index));
+ reg_val |= E1000_TXDCTL_QUEUE_ENABLE;
+ E1000_WRITE_REG(hw, E1000_TXDCTL(tx_ring->index), reg_val);
}
static void
@@ -2021,30 +2100,17 @@ igb_setup_tx(igb_t *igb)
/*
* Setup the Transmit Control Register (TCTL)
*/
- reg_val = E1000_TCTL_PSP | E1000_TCTL_EN |
- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT) |
- (E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT) |
- E1000_TCTL_RTLC;
-
- /* Enable the MULR bit */
- if (hw->bus.type == e1000_bus_type_pci_express)
- reg_val |= E1000_TCTL_MULR;
+ reg_val = E1000_READ_REG(hw, E1000_TCTL);
+ reg_val &= ~E1000_TCTL_CT;
+ reg_val |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
+ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
- E1000_WRITE_REG(hw, E1000_TCTL, reg_val);
+ e1000_config_collision_dist(hw);
- /*
- * Set the default values for the Tx Inter Packet Gap timer
- */
- if (hw->phy.media_type == e1000_media_type_fiber)
- reg_val = DEFAULT_82543_TIPG_IPGT_FIBER;
- else
- reg_val = DEFAULT_82543_TIPG_IPGT_COPPER;
- reg_val |=
- DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
- reg_val |=
- DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
+ /* Enable transmits */
+ reg_val |= E1000_TCTL_EN;
- E1000_WRITE_REG(hw, E1000_TIPG, reg_val);
+ E1000_WRITE_REG(hw, E1000_TCTL, reg_val);
}
/*
@@ -2055,7 +2121,7 @@ igb_setup_rss(igb_t *igb)
{
struct e1000_hw *hw = &igb->hw;
uint32_t i, mrqc, rxcsum;
- int shift;
+ int shift = 0;
uint32_t random;
union e1000_reta {
uint32_t dword;
@@ -2063,7 +2129,11 @@ igb_setup_rss(igb_t *igb)
} reta;
/* Setup the Redirection Table */
- shift = 6;
+ if (hw->mac.type == e1000_82576) {
+ shift = 0;
+ } else if (hw->mac.type == e1000_82575) {
+ shift = 6;
+ }
for (i = 0; i < (32 * 4); i++) {
reta.bytes[i & 3] = (i % igb->num_rx_rings) << shift;
if ((i & 3) == 3) {
@@ -2166,7 +2236,7 @@ igb_setup_mac_rss_classify(igb_t *igb)
/* Define the default group and default queues */
vmdctl = E1000_VMDQ_MAC_GROUP_DEFAULT_QUEUE;
- E1000_WRITE_REG(hw, E1000_VMD_CTL, vmdctl);
+ E1000_WRITE_REG(hw, E1000_VT_CTL, vmdctl);
/*
* Disable Packet Checksum to enable RSS for multiple receive queues.
@@ -2499,7 +2569,7 @@ igb_get_conf(igb_t *igb)
if (flow_control == 4)
flow_control = e1000_fc_default;
- hw->fc.type = flow_control;
+ hw->fc.requested_mode = flow_control;
/*
* Multiple rings configurations
@@ -2512,10 +2582,16 @@ igb_get_conf(igb_t *igb)
igb->mr_enable = igb_get_prop(igb, PROP_MR_ENABLE, 0, 1, 1);
igb->num_rx_groups = igb_get_prop(igb, PROP_RX_GROUP_NUM,
MIN_RX_GROUP_NUM, MAX_RX_GROUP_NUM, DEFAULT_RX_GROUP_NUM);
+ /*
+ * Currently we do not support VMDq for 82576.
+ * If it is e1000_82576, set num_rx_groups to 1.
+ */
+ if (hw->mac.type == e1000_82576)
+ igb->num_rx_groups = 1;
if (igb->mr_enable) {
- igb->num_tx_rings = DEFAULT_TX_QUEUE_NUM;
- igb->num_rx_rings = DEFAULT_RX_QUEUE_NUM;
+ igb->num_tx_rings = igb->capab->def_tx_que_num;
+ igb->num_rx_rings = igb->capab->def_rx_que_num;
} else {
igb->num_tx_rings = 1;
igb->num_rx_rings = 1;
@@ -2605,8 +2681,9 @@ igb_get_conf(igb_t *igb)
DEFAULT_RX_LIMIT_PER_INTR);
igb->intr_throttling[0] = igb_get_prop(igb, PROP_INTR_THROTTLING,
- MIN_INTR_THROTTLING, MAX_INTR_THROTTLING,
- DEFAULT_INTR_THROTTLING);
+ igb->capab->min_intr_throttle,
+ igb->capab->max_intr_throttle,
+ igb->capab->def_intr_throttle);
}
/*
@@ -3090,24 +3167,55 @@ igb_disable_adapter_interrupts(igb_t *igb)
* Set the IMC register to mask all the interrupts,
* including the tx interrupts.
*/
- E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
+ E1000_WRITE_REG(hw, E1000_IMC, ~0);
+ E1000_WRITE_REG(hw, E1000_IAM, 0);
/*
* Additional disabling for MSI-X
*/
if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
- E1000_WRITE_REG(hw, E1000_EIMC, 0xffffffff);
- E1000_WRITE_REG(hw, E1000_EIAC, 0x0);
+ E1000_WRITE_REG(hw, E1000_EIMC, ~0);
+ E1000_WRITE_REG(hw, E1000_EIAC, 0);
+ E1000_WRITE_REG(hw, E1000_EIAM, 0);
}
E1000_WRITE_FLUSH(hw);
}
/*
- * igb_enable_adapter_interrupts - Mask/enable all hardware interrupts
+ * igb_enable_adapter_interrupts_82576 - Enable NIC interrupts for 82576
*/
static void
-igb_enable_adapter_interrupts(igb_t *igb)
+igb_enable_adapter_interrupts_82576(igb_t *igb)
+{
+ struct e1000_hw *hw = &igb->hw;
+
+ if (igb->intr_type == DDI_INTR_TYPE_MSIX) {
+
+ /* Interrupt enabling for MSI-X */
+ E1000_WRITE_REG(hw, E1000_EIMS, igb->eims_mask);
+ E1000_WRITE_REG(hw, E1000_EIAC, igb->eims_mask);
+ igb->ims_mask = E1000_IMS_LSC;
+ E1000_WRITE_REG(hw, E1000_IMS, E1000_IMS_LSC);
+ } else {
+ /* Interrupt enabling for MSI and legacy */
+ E1000_WRITE_REG(hw, E1000_IVAR0, E1000_IVAR_VALID);
+ igb->ims_mask = IMS_ENABLE_MASK | E1000_IMS_TXQE;
+ E1000_WRITE_REG(hw, E1000_IMS,
+ (IMS_ENABLE_MASK | E1000_IMS_TXQE));
+ }
+
+ /* Disable auto-mask for ICR interrupt bits */
+ E1000_WRITE_REG(hw, E1000_IAM, 0);
+
+ E1000_WRITE_FLUSH(hw);
+}
+
+/*
+ * igb_enable_adapter_interrupts_82575 - Enable NIC interrupts for 82575
+ */
+static void
+igb_enable_adapter_interrupts_82575(igb_t *igb)
{
struct e1000_hw *hw = &igb->hw;
uint32_t reg;
@@ -3530,6 +3638,9 @@ igb_intr_legacy(void *arg1, void *arg2)
ASSERT(igb->num_rx_rings == 1);
ASSERT(igb->num_tx_rings == 1);
+ /* Make sure all interrupt causes cleared */
+ (void) E1000_READ_REG(&igb->hw, E1000_EICR);
+
if (icr & E1000_ICR_RXT0) {
mp = igb_rx(&igb->rx_rings[0], IGB_NO_POLL);
}
@@ -3601,6 +3712,9 @@ igb_intr_msi(void *arg1, void *arg2)
icr = E1000_READ_REG(&igb->hw, E1000_ICR);
+ /* Make sure all interrupt causes cleared */
+ (void) E1000_READ_REG(&igb->hw, E1000_EICR);
+
/*
* For MSI interrupt, we have only one vector,
* so we have only one rx ring and one tx ring enabled.
@@ -4055,19 +4169,20 @@ igb_add_intr_handlers(igb_t *igb)
}
/*
- * igb_setup_adapter_msix - setup the adapter to use MSI-X interrupts
+ * igb_setup_msix_82575 - setup 82575 adapter to use MSI-X interrupts
*
* For each vector enabled on the adapter, Set the MSIXBM register accordingly
*/
static void
-igb_setup_adapter_msix(igb_t *igb)
+igb_setup_msix_82575(igb_t *igb)
{
uint32_t eims = 0;
int i, vector;
struct e1000_hw *hw = &igb->hw;
/*
- * Set vector for other causes, NOTE assumption that it is vector 0
+ * Set vector for tx ring 0 and other causes.
+ * NOTE assumption that it is vector 0.
*/
vector = 0;
@@ -4083,7 +4198,8 @@ igb_setup_adapter_msix(igb_t *igb)
E1000_WRITE_REG(hw, E1000_MSIXBM(vector), eims);
/*
- * Accumulate bits to enable in igb_enable_adapter_interrupts()
+ * Accumulate bits to enable in
+ * igb_enable_adapter_interrupts_82575()
*/
igb->eims_mask |= eims;
@@ -4098,7 +4214,8 @@ igb_setup_adapter_msix(igb_t *igb)
E1000_WRITE_REG(hw, E1000_MSIXBM(vector), eims);
/*
- * Accumulate bits to enable in igb_enable_adapter_interrupts()
+ * Accumulate bits to enable in
+ * igb_enable_adapter_interrupts_82575()
*/
igb->eims_mask |= eims;
@@ -4115,6 +4232,98 @@ igb_setup_adapter_msix(igb_t *igb)
}
/*
+ * igb_setup_msix_82576 - setup 82576 adapter to use MSI-X interrupts
+ *
+ * 82576 uses a table based method for assigning vectors. Each queue has a
+ * single entry in the table to which we write a vector number along with a
+ * "valid" bit. The entry is a single byte in a 4-byte register. Vectors
+ * take a different position in the 4-byte register depending on whether
+ * they are numbered above or below 8.
+ */
+static void
+igb_setup_msix_82576(igb_t *igb)
+{
+ struct e1000_hw *hw = &igb->hw;
+ uint32_t ivar, index, vector;
+ int i;
+
+ /* must enable msi-x capability before IVAR settings */
+ E1000_WRITE_REG(hw, E1000_GPIE,
+ (E1000_GPIE_MSIX_MODE | E1000_GPIE_PBA | E1000_GPIE_NSICR));
+
+ /*
+ * Set vector for tx ring 0 and other causes.
+ * NOTE assumption that it is vector 0.
+ * This is also interdependent with installation of interrupt service
+ * routines in igb_add_intr_handlers().
+ */
+
+ /* assign "other" causes to vector 0 */
+ vector = 0;
+ ivar = ((vector | E1000_IVAR_VALID) << 8);
+ E1000_WRITE_REG(hw, E1000_IVAR_MISC, ivar);
+
+ /* assign tx ring 0 to vector 0 */
+ ivar = ((vector | E1000_IVAR_VALID) << 8);
+ E1000_WRITE_REG(hw, E1000_IVAR0, ivar);
+
+ /* prepare to enable tx & other interrupt causes */
+ igb->eims_mask = (1 << vector);
+
+ vector ++;
+ for (i = 0; i < igb->num_rx_rings; i++) {
+ /*
+ * Set vector for each rx ring
+ */
+ index = (i & 0x7);
+ ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
+
+ if (i < 8) {
+ /* vector goes into low byte of register */
+ ivar = ivar & 0xFFFFFF00;
+ ivar |= (vector | E1000_IVAR_VALID);
+ } else {
+ /* vector goes into third byte of register */
+ ivar = ivar & 0xFF00FFFF;
+ ivar |= ((vector | E1000_IVAR_VALID) << 16);
+ }
+ E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
+
+ /* Accumulate interrupt-cause bits to enable */
+ igb->eims_mask |= (1 << vector);
+
+ vector ++;
+ }
+
+ for (i = 1; i < igb->num_tx_rings; i++) {
+ /*
+ * Set vector for each tx ring from 2nd tx ring.
+ * Note assumption that tx vectors numericall follow rx vectors.
+ */
+ index = (i & 0x7);
+ ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
+
+ if (i < 8) {
+ /* vector goes into second byte of register */
+ ivar = ivar & 0xFFFF00FF;
+ ivar |= ((vector | E1000_IVAR_VALID) << 8);
+ } else {
+ /* vector goes into fourth byte of register */
+ ivar = ivar & 0x00FFFFFF;
+ ivar |= (vector | E1000_IVAR_VALID) << 24;
+ }
+ E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
+
+ /* Accumulate interrupt-cause bits to enable */
+ igb->eims_mask |= (1 << vector);
+
+ vector ++;
+ }
+
+ ASSERT(vector == igb->intr_cnt);
+}
+
+/*
* igb_rem_intr_handlers - remove the interrupt handlers
*/
static void
diff --git a/usr/src/uts/common/io/igb/igb_manage.c b/usr/src/uts/common/io/igb/igb_manage.c
index 56715fbb3b..d34df442af 100644
--- a/usr/src/uts/common/io/igb/igb_manage.c
+++ b/usr/src/uts/common/io/igb/igb_manage.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,16 +22,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.19 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.27 v2008-10-7 */
#include "igb_api.h"
-#include "igb_manage.h"
static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
@@ -65,7 +62,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length)
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
- * This function checks whether the HOST IF is enabled for command operaton
+ * This function checks whether the HOST IF is enabled for command operation
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
*/
@@ -104,7 +101,7 @@ out:
}
/*
- * e1000_check_mng_mode_generic - Generic check managament mode
+ * e1000_check_mng_mode_generic - Generic check management mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
@@ -138,13 +135,13 @@ e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
- bool tx_filter = TRUE;
+ bool tx_filter = true;
DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
/* No manageability, no filtering */
- if (!e1000_check_mng_mode(hw)) {
- tx_filter = FALSE;
+ if (!hw->mac.ops.check_mng_mode(hw)) {
+ tx_filter = false;
goto out;
}
@@ -152,9 +149,9 @@ e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
- ret_val = e1000_mng_enable_host_if(hw);
+ ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val != E1000_SUCCESS) {
- tx_filter = FALSE;
+ tx_filter = false;
goto out;
}
@@ -181,7 +178,7 @@ e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
- tx_filter = FALSE;
+ tx_filter = false;
out:
hw->mac.tx_pkt_filtering = tx_filter;
@@ -213,18 +210,18 @@ e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
hdr.checksum = 0;
/* Enable the host interface */
- ret_val = e1000_mng_enable_host_if(hw);
+ ret_val = hw->mac.ops.mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
- ret_val = e1000_mng_host_if_write(hw, buffer, length,
+ ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
sizeof (hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
- ret_val = e1000_mng_write_cmd_header(hw, &hdr);
+ ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
if (ret_val)
goto out;
@@ -359,7 +356,7 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
- bool ret_val = FALSE;
+ bool ret_val = false;
DEBUGFUNC("e1000_enable_mng_pass_thru");
@@ -379,13 +376,13 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw)
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
- ret_val = TRUE;
+ ret_val = true;
goto out;
}
} else {
if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
- ret_val = TRUE;
+ ret_val = true;
goto out;
}
}
diff --git a/usr/src/uts/common/io/igb/igb_manage.h b/usr/src/uts/common/io/igb/igb_manage.h
index 7168a5cf44..4972bf6734 100644
--- a/usr/src/uts/common/io/igb/igb_manage.h
+++ b/usr/src/uts/common/io/igb/igb_manage.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.15 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.18 v2008-10-7 */
#ifndef _IGB_MANAGE_H
#define _IGB_MANAGE_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -46,14 +44,15 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
u8 *buffer, u16 length);
+bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
-typedef enum {
+enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
-} e1000_mng_mode;
+};
#define E1000_FACTPS_MNGCG 0x20000000
diff --git a/usr/src/uts/common/io/igb/igb_ndd.c b/usr/src/uts/common/io/igb/igb_ndd.c
index 93a0353caa..58ce0e77e5 100644
--- a/usr/src/uts/common/io/igb/igb_ndd.c
+++ b/usr/src/uts/common/io/igb/igb_ndd.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,12 +22,10 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "igb_sw.h"
/* Function prototypes */
@@ -339,7 +337,7 @@ igb_nd_ioctl(igb_t *igb, queue_t *q,
switch (cmd) {
default:
/* NOTREACHED */
- ASSERT(FALSE);
+ ASSERT(B_FALSE);
return (IOC_INVAL);
case ND_GET:
diff --git a/usr/src/uts/common/io/igb/igb_nvm.c b/usr/src/uts/common/io/igb/igb_nvm.c
index 8949a10caf..4552f9e54f 100644
--- a/usr/src/uts/common/io/igb/igb_nvm.c
+++ b/usr/src/uts/common/io/igb/igb_nvm.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,16 +22,87 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.35 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.46 v2008-10-7 */
#include "igb_api.h"
-#include "igb_nvm.h"
+
+static void e1000_stop_nvm(struct e1000_hw *hw);
+static void e1000_reload_nvm_generic(struct e1000_hw *hw);
+
+/*
+ * e1000_init_nvm_ops_generic - Initialize NVM function pointers
+ * @hw: pointer to the HW structure
+ *
+ * Setups up the function pointers to no-op functions
+ */
+void
+e1000_init_nvm_ops_generic(struct e1000_hw *hw)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ DEBUGFUNC("e1000_init_nvm_ops_generic");
+
+ /* Initialize function pointers */
+ nvm->ops.init_params = e1000_null_ops_generic;
+ nvm->ops.acquire = e1000_null_ops_generic;
+ nvm->ops.read = e1000_null_read_nvm;
+ nvm->ops.release = e1000_null_nvm_generic;
+ nvm->ops.reload = e1000_reload_nvm_generic;
+ nvm->ops.update = e1000_null_ops_generic;
+ nvm->ops.valid_led_default = e1000_null_led_default;
+ nvm->ops.validate = e1000_null_ops_generic;
+ nvm->ops.write = e1000_null_write_nvm;
+}
+
+/*
+ * e1000_null_nvm_read - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+{
+ DEBUGFUNC("e1000_null_read_nvm");
+ UNREFERENCED_4PARAMETER(hw, a, b, c);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_nvm_generic - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_nvm_generic(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_null_nvm_generic");
+ UNREFERENCED_1PARAMETER(hw);
+}
+
+/*
+ * e1000_null_led_default - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_led_default(struct e1000_hw *hw, u16 *data)
+{
+ DEBUGFUNC("e1000_null_led_default");
+ UNREFERENCED_2PARAMETER(hw, data);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_write_nvm - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
+{
+ DEBUGFUNC("e1000_null_write_nvm");
+ UNREFERENCED_4PARAMETER(hw, a, b, c);
+ return (E1000_SUCCESS);
+}
/*
* e1000_raise_eec_clk - Raise EEPROM clock
@@ -285,7 +356,7 @@ e1000_stop_nvm(struct e1000_hw *hw)
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
- /* CS on Microcwire is active-high */
+ /* CS on Microwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
e1000_raise_eec_clk(hw, &eecd);
@@ -374,71 +445,6 @@ out:
}
/*
- * e1000_read_nvm_spi - Read EEPROM's using SPI
- * @hw: pointer to the HW structure
- * @offset: offset of word in the EEPROM to read
- * @words: number of words to read
- * @data: word read from the EEPROM
- *
- * Reads a 16 bit word from the EEPROM.
- */
-s32
-e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
-{
- struct e1000_nvm_info *nvm = &hw->nvm;
- u32 i = 0;
- s32 ret_val;
- u16 word_in;
- u8 read_opcode = NVM_READ_OPCODE_SPI;
-
- DEBUGFUNC("e1000_read_nvm_spi");
-
- /*
- * A check for invalid values: offset too large, too many words,
- * and not enough words.
- */
- if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
- (words == 0)) {
- DEBUGOUT("nvm parameter(s) out of bounds\n");
- ret_val = -E1000_ERR_NVM;
- goto out;
- }
-
- ret_val = e1000_acquire_nvm(hw);
- if (ret_val)
- goto out;
-
- ret_val = e1000_ready_nvm_eeprom(hw);
- if (ret_val)
- goto release;
-
- e1000_standby_nvm(hw);
-
- if ((nvm->address_bits == 8) && (offset >= 128))
- read_opcode |= NVM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
- e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
-
- /*
- * Read the data. SPI NVMs increment the address with each byte
- * read and will roll over if reading beyond the end. This allows
- * us to read the whole NVM from any offset
- */
- for (i = 0; i < words; i++) {
- word_in = e1000_shift_in_eec_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
-
-release:
- e1000_release_nvm(hw);
-
-out:
- return (ret_val);
-}
-
-/*
* e1000_read_nvm_microwire - Reads EEPROM's using microwire
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
@@ -469,7 +475,7 @@ e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
goto out;
}
- ret_val = e1000_acquire_nvm(hw);
+ ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
@@ -492,7 +498,7 @@ e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
}
release:
- e1000_release_nvm(hw);
+ nvm->ops.release(hw);
out:
return (ret_val);
@@ -554,7 +560,7 @@ out:
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
*/
s32
e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
@@ -576,12 +582,10 @@ e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
goto out;
}
- ret_val = e1000_acquire_nvm(hw);
+ ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
- msec_delay(10);
-
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
@@ -625,7 +629,7 @@ e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
msec_delay(10);
release:
- e1000_release_nvm(hw);
+ nvm->ops.release(hw);
out:
return (ret_val);
@@ -641,7 +645,7 @@ out:
* Writes data to EEPROM at offset using microwire interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
- * EEPROM will most likley contain an invalid checksum.
+ * EEPROM will most likely contain an invalid checksum.
*/
s32
e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
@@ -666,7 +670,7 @@ e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
goto out;
}
- ret_val = e1000_acquire_nvm(hw);
+ ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
@@ -716,7 +720,7 @@ e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
release:
- e1000_release_nvm(hw);
+ nvm->ops.release(hw);
out:
return (ret_val);
@@ -738,14 +742,14 @@ e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
DEBUGFUNC("e1000_read_pba_num_generic");
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*pba_num = (u32)(nvm_data << 16);
- ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@@ -774,7 +778,7 @@ e1000_read_mac_addr_generic(struct e1000_hw *hw)
for (i = 0; i < ETH_ADDR_LEN; i += 2) {
offset = i >> 1;
- ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@@ -811,7 +815,7 @@ e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_validate_nvm_checksum_generic");
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
@@ -847,7 +851,7 @@ e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_update_nvm_checksum");
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
@@ -855,10 +859,9 @@ e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
- ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
- if (ret_val) {
+ ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
+ if (ret_val)
DEBUGOUT("NVM Write Error while updating checksum.\n");
- }
out:
return (ret_val);
@@ -884,35 +887,3 @@ e1000_reload_nvm_generic(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}
-
-/* Function pointers local to this file and not intended for public use */
-
-/*
- * e1000_acquire_nvm - Acquire exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * For those silicon families which have implemented a NVM acquire function,
- * run the defined function else return success.
- */
-s32
-e1000_acquire_nvm(struct e1000_hw *hw)
-{
- if (hw->func.acquire_nvm)
- return (hw->func.acquire_nvm(hw));
-
- return (E1000_SUCCESS);
-}
-
-/*
- * e1000_release_nvm - Release exclusive access to EEPROM
- * @hw: pointer to the HW structure
- *
- * For those silicon families which have implemented a NVM release function,
- * run the defined fucntion else return success.
- */
-void
-e1000_release_nvm(struct e1000_hw *hw)
-{
- if (hw->func.release_nvm)
- hw->func.release_nvm(hw);
-}
diff --git a/usr/src/uts/common/io/igb/igb_nvm.h b/usr/src/uts/common/io/igb/igb_nvm.h
index 01b4f9dc6e..f5a96bd89a 100644
--- a/usr/src/uts/common/io/igb/igb_nvm.h
+++ b/usr/src/uts/common/io/igb/igb_nvm.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,27 +22,29 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.13 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.18 v2008-10-7 */
#ifndef _IGB_NVM_H
#define _IGB_NVM_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
+void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
+s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
+void e1000_null_nvm_generic(struct e1000_hw *hw);
+s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data);
+s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num);
-s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words,
@@ -56,13 +58,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset,
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
-void e1000_stop_nvm(struct e1000_hw *hw);
void e1000_release_nvm_generic(struct e1000_hw *hw);
-void e1000_reload_nvm_generic(struct e1000_hw *hw);
-
-/* Function pointers */
-s32 e1000_acquire_nvm(struct e1000_hw *hw);
-void e1000_release_nvm(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
diff --git a/usr/src/uts/common/io/igb/igb_osdep.c b/usr/src/uts/common/io/igb/igb_osdep.c
index f915edd5ae..99151cd10f 100644
--- a/usr/src/uts/common/io/igb/igb_osdep.c
+++ b/usr/src/uts/common/io/igb/igb_osdep.c
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,36 +22,14 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
#include "igb_osdep.h"
#include "igb_api.h"
-s32
-e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size)
-{
- hw->dev_spec = kmem_zalloc(size, KM_SLEEP);
-
- return (E1000_SUCCESS);
-}
-
-void
-e1000_free_dev_spec_struct(struct e1000_hw *hw)
-{
- if (hw->dev_spec == NULL)
- return;
-
- kmem_free(hw->dev_spec, hw->dev_spec_size);
- hw->dev_spec = NULL;
-}
-
void
e1000_pci_set_mwi(struct e1000_hw *hw)
{
diff --git a/usr/src/uts/common/io/igb/igb_osdep.h b/usr/src/uts/common/io/igb/igb_osdep.h
index f56f320a1c..158e753909 100644
--- a/usr/src/uts/common/io/igb/igb_osdep.h
+++ b/usr/src/uts/common/io/igb/igb_osdep.h
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,12 +22,8 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
#ifndef _IGB_OSDEP_H
@@ -56,25 +54,26 @@ extern "C" {
#define usec_delay(x) drv_usecwait(x)
#define msec_delay(x) drv_usecwait(x * 1000)
+#define msec_delay_irq msec_delay
#ifdef IGB_DEBUG
#define DEBUGOUT(S) IGB_DEBUGLOG_0(NULL, S)
#define DEBUGOUT1(S, A) IGB_DEBUGLOG_1(NULL, S, A)
#define DEBUGOUT2(S, A, B) IGB_DEBUGLOG_2(NULL, S, A, B)
#define DEBUGOUT3(S, A, B, C) IGB_DEBUGLOG_3(NULL, S, A, B, C)
-#define DEBUGFUNC(F)
#else
#define DEBUGOUT(S)
#define DEBUGOUT1(S, A)
#define DEBUGOUT2(S, A, B)
#define DEBUGOUT3(S, A, B, C)
-#define DEBUGFUNC(F)
#endif
+#define DEBUGFUNC(F)
+
#define OS_DEP(hw) ((struct igb_osdep *)((hw)->back))
-#define FALSE 0
-#define TRUE 1
+#define false B_FALSE
+#define true B_TRUE
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER 0x04
@@ -132,9 +131,16 @@ extern "C" {
#define E1000_READ_REG_ARRAY_DWORD(a, reg, offset) \
E1000_READ_REG_ARRAY(a, reg, offset)
-#define msec_delay_irq msec_delay
+#define UNREFERENCED_1PARAMETER(_p) _NOTE(ARGUNUSED(_p))
+#define UNREFERENCED_2PARAMETER(_p, _q) _NOTE(ARGUNUSED(_p, _q))
+#define UNREFERENCED_3PARAMETER(_p, _q, _r) _NOTE(ARGUNUSED(_p, _q, _r))
+#define UNREFERENCED_4PARAMETER(_p, _q, _r, _s) _NOTE(ARGUNUSED(_p, _q, _r, _s))
+#define UNREFERENCED_5PARAMETER(_p, _q, _r, _s, _t) \
+ _NOTE(ARGUNUSED(_p, _q, _r, _s, _t))
-#define UNREFERENCED_PARAMETER(x) _NOTE(ARGUNUSED(x))
+#define __le16 u16
+#define __le32 u32
+#define __le64 u64
typedef int8_t s8;
typedef int16_t s16;
diff --git a/usr/src/uts/common/io/igb/igb_phy.c b/usr/src/uts/common/io/igb/igb_phy.c
index 5cc7304734..daf53a13e0 100644
--- a/usr/src/uts/common/io/igb/igb_phy.c
+++ b/usr/src/uts/common/io/igb/igb_phy.c
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,21 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.71 v2007-12-10_dragonlake5 */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
+/* IntelVersion: 1.112 v2008-10-7 */
#include "igb_api.h"
-#include "igb_phy.h"
-static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static void e1000_release_phy(struct e1000_hw *hw);
-static s32 e1000_acquire_phy(struct e1000_hw *hw);
-static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
+static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
@@ -61,6 +55,85 @@ static const u16 e1000_igp_2_cable_length_table[] =
sizeof (e1000_igp_2_cable_length_table[0]))
/*
+ * e1000_init_phy_ops_generic - Initialize PHY function pointers
+ * @hw: pointer to the HW structure
+ *
+ * Setups up the function pointers to no-op functions
+ */
+void
+e1000_init_phy_ops_generic(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ DEBUGFUNC("e1000_init_phy_ops_generic");
+
+ /* Initialize function pointers */
+ phy->ops.init_params = e1000_null_ops_generic;
+ phy->ops.acquire = e1000_null_ops_generic;
+ phy->ops.check_polarity = e1000_null_ops_generic;
+ phy->ops.check_reset_block = e1000_null_ops_generic;
+ phy->ops.commit = e1000_null_ops_generic;
+ phy->ops.force_speed_duplex = e1000_null_ops_generic;
+ phy->ops.get_cfg_done = e1000_null_ops_generic;
+ phy->ops.get_cable_length = e1000_null_ops_generic;
+ phy->ops.get_info = e1000_null_ops_generic;
+ phy->ops.read_reg = e1000_null_read_reg;
+ phy->ops.release = e1000_null_phy_generic;
+ phy->ops.reset = e1000_null_ops_generic;
+ phy->ops.set_d0_lplu_state = e1000_null_lplu_state;
+ phy->ops.set_d3_lplu_state = e1000_null_lplu_state;
+ phy->ops.write_reg = e1000_null_write_reg;
+ phy->ops.power_up = e1000_null_phy_generic;
+ phy->ops.power_down = e1000_null_phy_generic;
+}
+
+/*
+ * e1000_null_read_reg - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ DEBUGFUNC("e1000_null_read_reg");
+ UNREFERENCED_3PARAMETER(hw, offset, data);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_phy_generic - No-op function, return void
+ * @hw: pointer to the HW structure
+ */
+void
+e1000_null_phy_generic(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_null_phy_generic");
+ UNREFERENCED_1PARAMETER(hw);
+}
+
+/*
+ * e1000_null_lplu_state - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_lplu_state(struct e1000_hw *hw, bool active)
+{
+ DEBUGFUNC("e1000_null_lplu_state");
+ UNREFERENCED_2PARAMETER(hw, active);
+ return (E1000_SUCCESS);
+}
+
+/*
+ * e1000_null_write_reg - No-op function, return 0
+ * @hw: pointer to the HW structure
+ */
+s32
+e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ DEBUGFUNC("e1000_null_write_reg");
+ UNREFERENCED_3PARAMETER(hw, offset, data);
+ return (E1000_SUCCESS);
+}
+
+/*
* e1000_check_reset_block_generic - Check if PHY reset is blocked
* @hw: pointer to the HW structure
*
@@ -97,13 +170,16 @@ e1000_get_phy_id(struct e1000_hw *hw)
DEBUGFUNC("e1000_get_phy_id");
- ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id);
+ if (!(phy->ops.read_reg))
+ goto out;
+
+ ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
if (ret_val)
goto out;
phy->id = (u32)(phy_id << 16);
usec_delay(20);
- ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id);
+ ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
if (ret_val)
goto out;
@@ -123,15 +199,18 @@ out:
s32
e1000_phy_reset_dsp_generic(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_phy_reset_dsp_generic");
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
+ if (!(hw->phy.ops.write_reg))
+ goto out;
+
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
if (ret_val)
goto out;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
out:
return (ret_val);
@@ -143,7 +222,7 @@ out:
* @offset: register offset to be read
* @data: pointer to the read data
*
- * Reads the MDI control regsiter in the PHY at offset and stores the
+ * Reads the MDI control register in the PHY at offset and stores the
* information read to data.
*/
s32
@@ -155,12 +234,6 @@ e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
DEBUGFUNC("e1000_read_phy_reg_mdic");
- if (offset > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", offset);
- ret_val = -E1000_ERR_PARAM;
- goto out;
- }
-
/*
* Set up Op-code, Phy Address, and register offset in the MDI
* Control register. The MAC will take care of interfacing with the
@@ -216,12 +289,6 @@ e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
DEBUGFUNC("e1000_write_phy_reg_mdic");
- if (offset > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", offset);
- ret_val = -E1000_ERR_PARAM;
- goto out;
- }
-
/*
* Set up Op-code, Phy Address, and register offset in the MDI
* Control register. The MAC will take care of interfacing with the
@@ -273,18 +340,21 @@ out:
s32
e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_phy_reg_m88");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset, data);
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -302,18 +372,21 @@ out:
s32
e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_phy_reg_m88");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
ret_val = e1000_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset, data);
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -332,11 +405,14 @@ out:
s32
e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_phy_reg_igp");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -344,7 +420,7 @@ e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
ret_val = e1000_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT, (u16)offset);
if (ret_val) {
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
@@ -352,7 +428,7 @@ e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
ret_val = e1000_read_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset, data);
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -370,11 +446,14 @@ out:
s32
e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_phy_reg_igp");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -382,7 +461,7 @@ e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
ret_val = e1000_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT, (u16)offset);
if (ret_val) {
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
@@ -390,7 +469,7 @@ e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
ret_val = e1000_write_phy_reg_mdic(hw,
MAX_PHY_REG_ADDRESS & offset, data);
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -410,11 +489,14 @@ s32
e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data)
{
u32 kmrnctrlsta;
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_kmrn_reg_generic");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -427,7 +509,7 @@ e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data)
kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
*data = (u16)kmrnctrlsta;
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -447,11 +529,14 @@ s32
e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
{
u32 kmrnctrlsta;
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_kmrn_reg_generic");
- ret_val = e1000_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -460,7 +545,7 @@ e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
usec_delay(2);
- e1000_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return (ret_val);
@@ -488,13 +573,11 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw)
}
/* Enable CRS on TX. This must be set for half-duplex operation. */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
- /* For newer PHYs this bit is downshift enable */
- if (phy->type == e1000_phy_m88)
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
/*
* Options:
@@ -533,23 +616,17 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw)
if (phy->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
- /* Enable downshift on BM (disabled by default) */
- if (phy->type == e1000_phy_bm)
- phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
- if ((phy->type == e1000_phy_m88) &&
- (phy->revision < E1000_REVISION_4) &&
- (phy->id != BME1000_E_PHY_ID_R2)) {
+ if (phy->revision < E1000_REVISION_4) {
/*
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
- ret_val = e1000_read_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ &phy_data);
if (ret_val)
goto out;
@@ -567,14 +644,14 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw)
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
}
- ret_val = e1000_write_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+ phy_data);
if (ret_val)
goto out;
}
/* Commit the changes. */
- ret_val = e1000_phy_commit(hw);
+ ret_val = phy->ops.commit(hw);
if (ret_val) {
DEBUGOUT("Error committing the PHY changes\n");
goto out;
@@ -605,14 +682,17 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
goto out;
}
- ret_val = e1000_phy_hw_reset(hw);
+ ret_val = hw->phy.ops.reset(hw);
if (ret_val) {
DEBUGOUT("Error resetting the PHY.\n");
goto out;
}
- /* Wait 15ms for MAC to configure PHY from NVM settings. */
- msec_delay(15);
+ /*
+ * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
+ * timeout issues when LFS is enabled.
+ */
+ msec_delay(100);
/*
* The NVM settings will configure LPLU in D3 for
@@ -620,7 +700,7 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->type == e1000_phy_igp) {
/* disable lplu d3 during driver init */
- ret_val = e1000_set_d3_lplu_state(hw, FALSE);
+ ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
if (ret_val) {
DEBUGOUT("Error Disabling LPLU D3\n");
goto out;
@@ -628,13 +708,15 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
}
/* disable lplu d0 during driver init */
- ret_val = e1000_set_d0_lplu_state(hw, FALSE);
- if (ret_val) {
- DEBUGOUT("Error Disabling LPLU D0\n");
- goto out;
+ if (hw->phy.ops.set_d0_lplu_state) {
+ ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
+ if (ret_val) {
+ DEBUGOUT("Error Disabling LPLU D0\n");
+ goto out;
+ }
}
/* Configure mdi-mdix settings */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
if (ret_val)
goto out;
@@ -652,7 +734,7 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
data |= IGP01E1000_PSCR_AUTO_MDIX;
break;
}
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
if (ret_val)
goto out;
@@ -665,29 +747,29 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
/* Set auto Master/Slave resolution process */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
data &= ~CR_1000T_MS_ENABLE;
- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
@@ -711,7 +793,7 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw)
default:
break;
}
- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
@@ -763,12 +845,12 @@ e1000_copper_link_autoneg(struct e1000_hw *hw)
* Restart auto-negotiation by setting the Auto Neg Enable bit and
* the Auto Neg Restart bit in the PHY control register.
*/
- ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -777,7 +859,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw)
* check at a later time (for example, callback routine).
*/
if (phy->autoneg_wait_to_complete) {
- ret_val = e1000_wait_autoneg(hw);
+ ret_val = hw->mac.ops.wait_autoneg(hw);
if (ret_val) {
DEBUGOUT("Error while waiting for "
"autoneg to complete\n");
@@ -785,7 +867,7 @@ e1000_copper_link_autoneg(struct e1000_hw *hw)
}
}
- hw->mac.get_link_status = TRUE;
+ hw->mac.get_link_status = true;
out:
return (ret_val);
@@ -813,14 +895,14 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
phy->autoneg_advertised &= phy->autoneg_mask;
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
+ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
if (ret_val)
goto out;
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
/* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = e1000_read_phy_reg(hw,
- PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
+ &mii_1000t_ctrl_reg);
if (ret_val)
goto out;
}
@@ -871,9 +953,8 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
}
/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
- if (phy->autoneg_advertised & ADVERTISE_1000_HALF) {
+ if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
- }
/* Do we want to advertise 1000 Mb Full Duplex? */
if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
@@ -899,7 +980,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
* other: No software override. The flow control configuration
* in the EEPROM is used.
*/
- switch (hw->fc.type) {
+ switch (hw->fc.current_mode) {
case e1000_fc_none:
/*
* Flow control (Rx & Tx) is completely disabled by a
@@ -941,14 +1022,14 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw)
goto out;
}
- ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
+ ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
if (ret_val)
goto out;
DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
PHY_1000T_CTRL, mii_1000t_ctrl_reg);
if (ret_val)
goto out;
@@ -989,7 +1070,7 @@ e1000_setup_copper_link_generic(struct e1000_hw *hw)
* depending on user settings.
*/
DEBUGOUT("Forcing Speed and Duplex\n");
- ret_val = e1000_phy_force_speed_duplex(hw);
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
DEBUGOUT("Error Forcing Speed and Duplex\n");
goto out;
@@ -1037,13 +1118,13 @@ e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_force_speed_duplex_igp");
- ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
e1000_phy_force_speed_duplex_setup(hw, &phy_data);
- ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
@@ -1051,14 +1132,14 @@ e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
if (ret_val)
goto out;
@@ -1076,9 +1157,8 @@ e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
if (ret_val)
goto out;
- if (!link) {
+ if (!link)
DEBUGOUT("Link taking longer than expected.\n");
- }
/* Try once more */
ret_val = e1000_phy_has_link_generic(hw,
@@ -1117,39 +1197,37 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
- ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
e1000_phy_force_speed_duplex_setup(hw, &phy_data);
- /* Reset the phy to commit changes. */
- phy_data |= MII_CR_RESET;
-
- ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
- usec_delay(1);
+ /* Reset the phy to commit changes. */
+ ret_val = hw->phy.ops.commit(hw);
+ if (ret_val)
+ goto out;
if (phy->autoneg_wait_to_complete) {
DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n");
- ret_val = e1000_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
+ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
+ 100000, &link);
if (ret_val)
goto out;
@@ -1158,7 +1236,7 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* We didn't get link.
* Reset the DSP and cross our fingers.
*/
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
M88E1000_PHY_PAGE_SELECT,
0x001d);
if (ret_val)
@@ -1169,15 +1247,13 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
}
/* Try once more */
- ret_val = e1000_phy_has_link_generic(hw,
- PHY_FORCE_LIMIT,
- 100000,
- &link);
+ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
+ 100000, &link);
if (ret_val)
goto out;
}
- ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -1187,7 +1263,7 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* the reset value of 2.5MHz.
*/
phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
@@ -1195,12 +1271,12 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* In addition, we must re-enable CRS on Tx for both half and full
* duplex.
*/
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
out:
return (ret_val);
@@ -1227,7 +1303,7 @@ e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
DEBUGFUNC("e1000_phy_force_speed_duplex_setup");
/* Turn off flow control when forcing speed/duplex */
- hw->fc.type = e1000_fc_none;
+ hw->fc.current_mode = e1000_fc_none;
/* Force speed/duplex on the mac */
ctrl = E1000_READ_REG(hw, E1000_CTRL);
@@ -1288,18 +1364,21 @@ s32
e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
u16 data;
DEBUGFUNC("e1000_set_d3_lplu_state_generic");
- ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
+ if (!(hw->phy.ops.read_reg))
+ goto out;
+
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (!active) {
data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
@@ -1311,27 +1390,27 @@ e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
@@ -1341,21 +1420,21 @@ e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
(phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
(phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
data |= IGP02E1000_PM_D3_LPLU;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
}
@@ -1365,7 +1444,7 @@ out:
}
/*
- * e1000_check_downshift_generic - Checks whether a downshift in speed occured
+ * e1000_check_downshift_generic - Checks whether a downshift in speed occurred
* @hw: pointer to the HW structure
*
* Success returns 0, Failure returns 1
@@ -1384,7 +1463,6 @@ e1000_check_downshift_generic(struct e1000_hw *hw)
switch (phy->type) {
case e1000_phy_m88:
case e1000_phy_gg82563:
- case e1000_phy_bm:
offset = M88E1000_PHY_SPEC_STATUS;
mask = M88E1000_PSSR_DOWNSHIFT;
break;
@@ -1396,15 +1474,15 @@ e1000_check_downshift_generic(struct e1000_hw *hw)
break;
default:
/* speed downshift not supported */
- phy->speed_downgraded = FALSE;
+ phy->speed_downgraded = false;
ret_val = E1000_SUCCESS;
goto out;
}
- ret_val = e1000_read_phy_reg(hw, offset, &phy_data);
+ ret_val = phy->ops.read_reg(hw, offset, &phy_data);
if (!ret_val)
- phy->speed_downgraded = (phy_data & mask) ? TRUE : FALSE;
+ phy->speed_downgraded = (phy_data & mask) ? true : false;
out:
return (ret_val);
@@ -1427,7 +1505,7 @@ e1000_check_polarity_m88(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_polarity_m88");
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
if (!ret_val)
phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
@@ -1459,7 +1537,7 @@ e1000_check_polarity_igp(struct e1000_hw *hw)
* Polarity is determined based on the speed of
* our connection.
*/
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
@@ -1476,7 +1554,7 @@ e1000_check_polarity_igp(struct e1000_hw *hw)
mask = IGP01E1000_PSSR_POLARITY_REVERSED;
}
- ret_val = e1000_read_phy_reg(hw, offset, &data);
+ ret_val = phy->ops.read_reg(hw, offset, &data);
if (!ret_val)
phy->cable_polarity = (data & mask)
@@ -1488,7 +1566,7 @@ out:
}
/*
- * e1000_wait_autoneg_generic - Wait for auto-neg compeletion
+ * e1000_wait_autoneg_generic - Wait for auto-neg completion
* @hw: pointer to the HW structure
*
* Waits for auto-negotiation to complete or for the auto-negotiation time
@@ -1502,12 +1580,15 @@ e1000_wait_autoneg_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_wait_autoneg_generic");
+ if (!(hw->phy.ops.read_reg))
+ return (E1000_SUCCESS);
+
/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_AUTONEG_COMPLETE)
@@ -1540,16 +1621,19 @@ e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
DEBUGFUNC("e1000_phy_has_link_generic");
+ if (!(hw->phy.ops.read_reg))
+ return (E1000_SUCCESS);
+
for (i = 0; i < iterations; i++) {
/*
* Some PHYs require the PHY_STATUS register to be read
* twice due to the link bit being sticky. No harm doing
* it across the board.
*/
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_LINK_STATUS)
@@ -1560,7 +1644,7 @@ e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
usec_delay(usec_interval);
}
- *success = (i < iterations) ? TRUE : FALSE;
+ *success = (i < iterations) ? true : false;
return (ret_val);
}
@@ -1589,16 +1673,21 @@ e1000_get_cable_length_m88(struct e1000_hw *hw)
DEBUGFUNC("e1000_get_cable_length_m88");
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
M88E1000_PSSR_CABLE_LENGTH_SHIFT;
- phy->min_cable_length = e1000_m88_cable_length_table[index];
- phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+ if (index < (M88E1000_CABLE_LENGTH_TABLE_SIZE + 1)) {
+ phy->min_cable_length = e1000_m88_cable_length_table[index];
+ phy->max_cable_length = e1000_m88_cable_length_table[index+1];
- phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
+ phy->cable_length = (phy->min_cable_length +
+ phy->max_cable_length) / 2;
+ } else {
+ ret_val = E1000_ERR_PHY;
+ }
out:
return (ret_val);
@@ -1610,8 +1699,8 @@ out:
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which reperesent the
- * cobination of course and fine gain value, the value can be put
+ * cable. By reading the AGC registers, which represent the
+ * combination of coarse and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
*/
@@ -1633,13 +1722,13 @@ e1000_get_cable_length_igp_2(struct e1000_hw *hw)
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
+ ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
if (ret_val)
goto out;
/*
* Getting bits 15:9, which represent the combination of
- * course and fine gain values. The result is a number
+ * coarse and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
* approximate cable length.
*/
@@ -1715,30 +1804,29 @@ e1000_get_phy_info_m88(struct e1000_hw *hw)
goto out;
}
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
- ? TRUE
- : FALSE;
+ ? true : false;
ret_val = e1000_check_polarity_m88(hw);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
- phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? TRUE : FALSE;
+ phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- ret_val = e1000_get_cable_length(hw);
+ ret_val = hw->phy.ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
if (ret_val)
goto out;
@@ -1789,25 +1877,25 @@ e1000_get_phy_info_igp(struct e1000_hw *hw)
goto out;
}
- phy->polarity_correction = TRUE;
+ phy->polarity_correction = true;
ret_val = e1000_check_polarity_igp(hw);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
- phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? TRUE : FALSE;
+ phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? true : false;
if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
- ret_val = e1000_get_cable_length(hw);
+ ret_val = hw->phy.ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
if (ret_val)
goto out;
@@ -1838,17 +1926,20 @@ out:
s32
e1000_phy_sw_reset_generic(struct e1000_hw *hw)
{
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
u16 phy_ctrl;
DEBUGFUNC("e1000_phy_sw_reset_generic");
- ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ if (!(hw->phy.ops.read_reg))
+ goto out;
+
+ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= MII_CR_RESET;
- ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -1865,24 +1956,24 @@ out:
* Verify the reset block is not blocking us from resetting. Acquire
* semaphore (if necessary) and read/set/write the device control reset
* bit in the PHY. Wait the appropriate delay time for the device to
- * reset and relase the semaphore (if necessary).
+ * reset and release the semaphore (if necessary).
*/
s32
e1000_phy_hw_reset_generic(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
- s32 ret_val;
+ s32 ret_val = E1000_SUCCESS;
u32 ctrl;
DEBUGFUNC("e1000_phy_hw_reset_generic");
- ret_val = e1000_check_reset_block(hw);
+ ret_val = phy->ops.check_reset_block(hw);
if (ret_val) {
ret_val = E1000_SUCCESS;
goto out;
}
- ret_val = e1000_acquire_phy(hw);
+ ret_val = phy->ops.acquire(hw);
if (ret_val)
goto out;
@@ -1897,9 +1988,9 @@ e1000_phy_hw_reset_generic(struct e1000_hw *hw)
usec_delay(150);
- e1000_release_phy(hw);
+ phy->ops.release(hw);
- ret_val = e1000_get_phy_cfg_done(hw);
+ ret_val = phy->ops.get_cfg_done(hw);
out:
return (ret_val);
@@ -1916,77 +2007,13 @@ s32
e1000_get_cfg_done_generic(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_get_cfg_done_generic");
- UNREFERENCED_PARAMETER(hw);
+ UNREFERENCED_1PARAMETER(hw);
msec_delay_irq(10);
return (E1000_SUCCESS);
}
-/* Internal function pointers */
-
-/*
- * e1000_get_phy_cfg_done - Generic PHY configuration done
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family did not implement a family specific
- * get_cfg_done function.
- */
-static s32
-e1000_get_phy_cfg_done(struct e1000_hw *hw)
-{
- if (hw->func.get_cfg_done)
- return (hw->func.get_cfg_done(hw));
-
- return (E1000_SUCCESS);
-}
-
-/*
- * e1000_release_phy - Generic release PHY
- * @hw: pointer to the HW structure
- *
- * Return if silicon family does not require a semaphore when accessing the
- * PHY.
- */
-static void
-e1000_release_phy(struct e1000_hw *hw)
-{
- if (hw->func.release_phy)
- hw->func.release_phy(hw);
-}
-
-/*
- * e1000_acquire_phy - Generic acquire PHY
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family does not require a semaphore when
- * accessing the PHY.
- */
-static s32
-e1000_acquire_phy(struct e1000_hw *hw)
-{
- if (hw->func.acquire_phy)
- return (hw->func.acquire_phy(hw));
-
- return (E1000_SUCCESS);
-}
-
-/*
- * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
- * @hw: pointer to the HW structure
- *
- * When the silicon family has not implemented a forced speed/duplex
- * function for the PHY, simply return (E1000_SUCCESS).
- */
-s32
-e1000_phy_force_speed_duplex(struct e1000_hw *hw)
-{
- if (hw->func.force_speed_duplex)
- return (hw->func.force_speed_duplex(hw));
-
- return (E1000_SUCCESS);
-}
-
/*
* e1000_phy_init_script_igp3 - Inits the IGP3 PHY
* @hw: pointer to the HW structure
@@ -2000,75 +2027,75 @@ e1000_phy_init_script_igp3(struct e1000_hw *hw)
/* PHY init IGP 3 */
/* Enable rise/fall, 10-mode work in class-A */
- (void) e1000_write_phy_reg(hw, 0x2F5B, 0x9018);
+ (void) hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
/* Remove all caps from Replica path filter */
- (void) e1000_write_phy_reg(hw, 0x2F52, 0x0000);
+ (void) hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
/* Bias trimming for ADC, AFE and Driver (Default) */
- (void) e1000_write_phy_reg(hw, 0x2FB1, 0x8B24);
+ (void) hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
/* Increase Hybrid poly bias */
- (void) e1000_write_phy_reg(hw, 0x2FB2, 0xF8F0);
- /* Add 4% to Tx amplitude in Giga mode */
- (void) e1000_write_phy_reg(hw, 0x2010, 0x10B0);
+ (void) hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
+ /* Add 4% to Tx amplitude in Gig mode */
+ (void) hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
/* Disable trimming (TTT) */
- (void) e1000_write_phy_reg(hw, 0x2011, 0x0000);
+ (void) hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
/* Poly DC correction to 94.6% + 2% for all channels */
- (void) e1000_write_phy_reg(hw, 0x20DD, 0x249A);
+ (void) hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
/* ABS DC correction to 95.9% */
- (void) e1000_write_phy_reg(hw, 0x20DE, 0x00D3);
+ (void) hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
/* BG temp curve trim */
- (void) e1000_write_phy_reg(hw, 0x28B4, 0x04CE);
+ (void) hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
/* Increasing ADC OPAMP stage 1 currents to max */
- (void) e1000_write_phy_reg(hw, 0x2F70, 0x29E4);
+ (void) hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
/* Force 1000 ( required for enabling PHY regs configuration) */
- (void) e1000_write_phy_reg(hw, 0x0000, 0x0140);
+ (void) hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
/* Set upd_freq to 6 */
- (void) e1000_write_phy_reg(hw, 0x1F30, 0x1606);
+ (void) hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
/* Disable NPDFE */
- (void) e1000_write_phy_reg(hw, 0x1F31, 0xB814);
+ (void) hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
/* Disable adaptive fixed FFE (Default) */
- (void) e1000_write_phy_reg(hw, 0x1F35, 0x002A);
+ (void) hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
/* Enable FFE hysteresis */
- (void) e1000_write_phy_reg(hw, 0x1F3E, 0x0067);
+ (void) hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
/* Fixed FFE for short cable lengths */
- (void) e1000_write_phy_reg(hw, 0x1F54, 0x0065);
+ (void) hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
/* Fixed FFE for medium cable lengths */
- (void) e1000_write_phy_reg(hw, 0x1F55, 0x002A);
+ (void) hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
/* Fixed FFE for long cable lengths */
- (void) e1000_write_phy_reg(hw, 0x1F56, 0x002A);
+ (void) hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
/* Enable Adaptive Clip Threshold */
- (void) e1000_write_phy_reg(hw, 0x1F72, 0x3FB0);
+ (void) hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
/* AHT reset limit to 1 */
- (void) e1000_write_phy_reg(hw, 0x1F76, 0xC0FF);
+ (void) hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
/* Set AHT master delay to 127 msec */
- (void) e1000_write_phy_reg(hw, 0x1F77, 0x1DEC);
+ (void) hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
/* Set scan bits for AHT */
- (void) e1000_write_phy_reg(hw, 0x1F78, 0xF9EF);
+ (void) hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
/* Set AHT Preset bits */
- (void) e1000_write_phy_reg(hw, 0x1F79, 0x0210);
+ (void) hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
/* Change integ_factor of channel A to 3 */
- (void) e1000_write_phy_reg(hw, 0x1895, 0x0003);
+ (void) hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
/* Change prop_factor of channels BCD to 8 */
- (void) e1000_write_phy_reg(hw, 0x1796, 0x0008);
+ (void) hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
/* Change cg_icount + enable integbp for channels BCD */
- (void) e1000_write_phy_reg(hw, 0x1798, 0xD008);
+ (void) hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
/*
* Change cg_icount + enable integbp + change prop_factor_master
* to 8 for channel A
*/
- (void) e1000_write_phy_reg(hw, 0x1898, 0xD918);
+ (void) hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
/* Disable AHT in Slave mode on channel A */
- (void) e1000_write_phy_reg(hw, 0x187A, 0x0800);
+ (void) hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
/*
* Enable LPLU and disable AN to 1000 in non-D0a states,
* Enable SPD+B2B
*/
- (void) e1000_write_phy_reg(hw, 0x0019, 0x008D);
+ (void) hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
/* Enable restart AN on an1000_dis change */
- (void) e1000_write_phy_reg(hw, 0x001B, 0x2080);
+ (void) hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
/* Enable wh_fifo read clock in 10/100 modes */
- (void) e1000_write_phy_reg(hw, 0x0014, 0x0045);
+ (void) hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
/* Restart AN, Speed selection is 1000 */
- (void) e1000_write_phy_reg(hw, 0x0000, 0x1340);
+ (void) hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
return (E1000_SUCCESS);
}
@@ -2079,10 +2106,10 @@ e1000_phy_init_script_igp3(struct e1000_hw *hw)
*
* Returns the phy type from the id.
*/
-e1000_phy_type
+enum e1000_phy_type
e1000_get_phy_type_from_id(u32 phy_id)
{
- e1000_phy_type phy_type = e1000_phy_unknown;
+ enum e1000_phy_type phy_type = e1000_phy_unknown;
switch (phy_id) {
case M88E1000_I_PHY_ID:
@@ -2105,10 +2132,6 @@ e1000_get_phy_type_from_id(u32 phy_id)
case IFE_C_E_PHY_ID:
phy_type = e1000_phy_ife;
break;
- case BME1000_E_PHY_ID:
- case BME1000_E_PHY_ID_R2:
- phy_type = e1000_phy_bm;
- break;
default:
phy_type = e1000_phy_unknown;
break;
@@ -2117,408 +2140,6 @@ e1000_get_phy_type_from_id(u32 phy_id)
}
/*
- * e1000_determine_phy_address - Determines PHY address.
- * @hw: pointer to the HW structure
- *
- * This uses a trial and error method to loop through possible PHY
- * addresses. It tests each by reading the PHY ID registers and
- * checking for a match.
- */
-s32
-e1000_determine_phy_address(struct e1000_hw *hw)
-{
- s32 ret_val = -E1000_ERR_PHY_TYPE;
- u32 phy_addr = 0;
- u32 i = 0;
- e1000_phy_type phy_type = e1000_phy_unknown;
-
- do {
- for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) {
- hw->phy.addr = phy_addr;
- (void) e1000_get_phy_id(hw);
- phy_type = e1000_get_phy_type_from_id(hw->phy.id);
-
- /*
- * If phy_type is valid, break - we found our
- * PHY address
- */
- if (phy_type != e1000_phy_unknown) {
- ret_val = E1000_SUCCESS;
- break;
- }
- }
- i++;
- } while ((ret_val != E1000_SUCCESS) && (i < 100));
-
- return (ret_val);
-}
-
-/*
- * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
- * @page: page to access
- *
- * Returns the phy address for the page requested.
- */
-static u32
-e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
-{
- u32 phy_addr = 2;
-
- if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
- phy_addr = 1;
-
- return (phy_addr);
-}
-
-/*
- * e1000_write_phy_reg_bm - Write BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- */
-s32
-e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
- u32 page_select = 0;
- u32 page = offset >> IGP_PAGE_SHIFT;
- u32 page_shift = 0;
-
- DEBUGFUNC("e1000_write_phy_reg_bm");
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw,
- offset, &data, FALSE);
- goto out;
- }
-
- ret_val = e1000_acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- /*
- * Page select is register 31 for phy address 1 and 22 for
- * phy address 2 and 3. Page select is shifted only for
- * phy address 1.
- */
- if (hw->phy.addr == 1) {
- page_shift = IGP_PAGE_SHIFT;
- page_select = IGP01E1000_PHY_PAGE_SELECT;
- } else {
- page_shift = 0;
- page_select = BM_PHY_PAGE_SELECT;
- }
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000_write_phy_reg_mdic(hw, page_select,
- (page << page_shift));
- if (ret_val) {
- e1000_release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
-
- e1000_release_phy(hw);
-
-out:
- return (ret_val);
-}
-
-/*
- * e1000_read_phy_reg_bm - Read BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- */
-s32
-e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
- u32 page_select = 0;
- u32 page = offset >> IGP_PAGE_SHIFT;
- u32 page_shift = 0;
-
- DEBUGFUNC("e1000_write_phy_reg_bm");
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw,
- offset, data, TRUE);
- goto out;
- }
-
- ret_val = e1000_acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- /*
- * Page select is register 31 for phy address 1 and 22 for
- * phy address 2 and 3. Page select is shifted only for
- * phy address 1.
- */
- if (hw->phy.addr == 1) {
- page_shift = IGP_PAGE_SHIFT;
- page_select = IGP01E1000_PHY_PAGE_SELECT;
- } else {
- page_shift = 0;
- page_select = BM_PHY_PAGE_SELECT;
- }
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000_write_phy_reg_mdic(hw, page_select,
- (page << page_shift));
- if (ret_val) {
- e1000_release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
- e1000_release_phy(hw);
-
-out:
- return (ret_val);
-}
-
-/*
- * e1000_read_phy_reg_bm2 - Read BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read
- * @data: pointer to the read data
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting.
- */
-s32
-e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
-{
- s32 ret_val;
- u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
-
- DEBUGFUNC("e1000_write_phy_reg_bm2");
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw,
- offset, data, TRUE);
- goto out;
- }
-
- ret_val = e1000_acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = 1;
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
-
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000_write_phy_reg_mdic(hw,
- BM_PHY_PAGE_SELECT,
- page);
-
- if (ret_val) {
- e1000_release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
- e1000_release_phy(hw);
-
-out:
- return (ret_val);
-}
-
-/*
- * e1000_write_phy_reg_bm2 - Write BM PHY register
- * @hw: pointer to the HW structure
- * @offset: register offset to write to
- * @data: data to write at register offset
- *
- * Acquires semaphore, if necessary, then writes the data to PHY register
- * at the offset. Release any acquired semaphores before exiting.
- */
-s32
-e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data)
-{
- s32 ret_val;
- u16 page = (u16)(offset >> IGP_PAGE_SHIFT);
-
- DEBUGFUNC("e1000_write_phy_reg_bm2");
-
- /* Page 800 works differently than the rest so it has its own func */
- if (page == BM_WUC_PAGE) {
- ret_val = e1000_access_phy_wakeup_reg_bm(hw,
- offset, &data, FALSE);
- goto out;
- }
-
- ret_val = e1000_acquire_phy(hw);
- if (ret_val)
- goto out;
-
- hw->phy.addr = 1;
-
- if (offset > MAX_PHY_MULTI_PAGE_REG) {
- /* Page is shifted left, PHY expects (page x 32) */
- ret_val = e1000_write_phy_reg_mdic(hw,
- BM_PHY_PAGE_SELECT,
- page);
-
- if (ret_val) {
- e1000_release_phy(hw);
- goto out;
- }
- }
-
- ret_val = e1000_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
-
- e1000_release_phy(hw);
-
-out:
- return (ret_val);
-}
-
-/*
- * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
- * @hw: pointer to the HW structure
- * @offset: register offset to be read or written
- * @data: pointer to the data to read or write
- * @read: determines if operation is read or write
- *
- * Acquires semaphore, if necessary, then reads the PHY register at offset
- * and storing the retrieved information in data. Release any acquired
- * semaphores before exiting. Note that procedure to read the wakeup
- * registers are different. It works as such:
- * 1) Set page 769, register 17, bit 2 = 1
- * 2) Set page to 800 for host (801 if we were manageability)
- * 3) Write the address using the address opcode (0x11)
- * 4) Read or write the data using the data opcode (0x12)
- * 5) Restore 769_17.2 to its original value
- */
-s32
-e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw,
- u32 offset, u16 *data, bool read)
-{
- s32 ret_val;
- u16 reg = ((u16)offset) & PHY_REG_MASK;
- u16 phy_reg = 0;
- u8 phy_acquired = 1;
-
- DEBUGFUNC("e1000_read_phy_wakeup_reg_bm");
-
- ret_val = e1000_acquire_phy(hw);
- if (ret_val) {
- DEBUGOUT("Couldnt acquire PHY\n");
- phy_acquired = 0;
- goto out;
- }
-
- /* All operations in this function are phy address 1 */
- hw->phy.addr = 1;
-
- /* Set page 769 */
- (void) e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
-
- ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
- if (ret_val) {
- DEBUGOUT("Couldnt read PHY page 769\n");
- goto out;
- }
-
- /* First clear bit 4 to avoid a power state change */
- phy_reg &= ~(BM_WUC_HOST_WU_BIT);
- ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
- if (ret_val) {
- DEBUGOUT("Couldnt clear PHY page 769 bit 4\n");
- goto out;
- }
-
- /* Write bit 2 = 1, and clear bit 4 to 769_17 */
- ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
- phy_reg | BM_WUC_ENABLE_BIT);
- if (ret_val) {
- DEBUGOUT("Couldnt write PHY page 769 bit 2\n");
- goto out;
- }
-
- /* Select page 800 */
- ret_val = e1000_write_phy_reg_mdic(hw,
- IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_PAGE << IGP_PAGE_SHIFT));
-
- /* Write the page 800 offset value using opcode 0x11 */
- ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
- if (ret_val) {
- DEBUGOUT("Couldnt write address opcode to page 800\n");
- goto out;
- }
-
- if (read) {
- /* Read the page 800 value using opcode 0x12 */
- ret_val = e1000_read_phy_reg_mdic(hw,
- BM_WUC_DATA_OPCODE,
- data);
- } else {
- /* Read the page 800 value using opcode 0x12 */
- ret_val = e1000_write_phy_reg_mdic(hw,
- BM_WUC_DATA_OPCODE,
- *data);
- }
-
- if (ret_val) {
- DEBUGOUT("Couldnt read data value from page 800\n");
- goto out;
- }
-
- /*
- * Restore 769_17.2 to its original value
- * Set page 769
- */
- (void) e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
- (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
-
- /* Clear 769_17.2 */
- ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
- if (ret_val) {
- DEBUGOUT("Couldnt clear PHY page 769 bit 2\n");
- goto out;
- }
-
-out:
- if (phy_acquired == 1)
- e1000_release_phy(hw);
- return (ret_val);
-}
-
-/*
* e1000_power_up_phy_copper - Restore copper link in case of PHY power down
* @hw: pointer to the HW structure
*
@@ -2532,9 +2153,9 @@ e1000_power_up_phy_copper(struct e1000_hw *hw)
u16 mii_reg = 0;
/* The PHY will retain its settings across a power down/up cycle */
- (void) e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+ (void) hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg &= ~MII_CR_POWER_DOWN;
- (void) e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg);
+ (void) hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
}
/*
@@ -2551,8 +2172,8 @@ e1000_power_down_phy_copper(struct e1000_hw *hw)
u16 mii_reg = 0;
/* The PHY will retain its settings across a power down/up cycle */
- (void) e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg);
+ (void) hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
- (void) e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg);
+ (void) hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
msec_delay(1);
}
diff --git a/usr/src/uts/common/io/igb/igb_phy.h b/usr/src/uts/common/io/igb/igb_phy.h
index 2be5683e21..6a2cb12716 100644
--- a/usr/src/uts/common/io/igb/igb_phy.h
+++ b/usr/src/uts/common/io/igb/igb_phy.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,41 +22,29 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.39 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.55 v2008-10-7 */
#ifndef _IGB_PHY_H
#define _IGB_PHY_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
-
-typedef enum {
- e1000_ms_hw_default = 0,
- e1000_ms_force_master,
- e1000_ms_force_slave,
- e1000_ms_auto
-} e1000_ms_type;
-
-typedef enum {
- e1000_smart_speed_default = 0,
- e1000_smart_speed_on,
- e1000_smart_speed_off
-} e1000_smart_speed;
-
+void e1000_init_phy_ops_generic(struct e1000_hw *hw);
+s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data);
+void e1000_null_phy_generic(struct e1000_hw *hw);
+s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active);
+s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
-s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
@@ -71,7 +59,6 @@ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
-s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -85,14 +72,7 @@ s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
-e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
-s32 e1000_determine_phy_address(struct e1000_hw *hw);
-s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
-s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data,
- bool read);
-s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
+enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
void e1000_power_up_phy_copper(struct e1000_hw *hw);
void e1000_power_down_phy_copper(struct e1000_hw *hw);
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
@@ -113,18 +93,6 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
-#define BM_WUC_PAGE 800
-#define BM_WUC_ADDRESS_OPCODE 0x11
-#define BM_WUC_DATA_OPCODE 0x12
-#define BM_WUC_ENABLE_PAGE 769
-#define BM_WUC_ENABLE_REG 17
-#define BM_WUC_ENABLE_BIT (1 << 2)
-#define BM_WUC_HOST_WU_BIT (1 << 4)
-
-/* BM PHY Copper Specific Control 1 */
-#define BM_CS_CTRL1 16
-#define BM_CR_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */
-
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
diff --git a/usr/src/uts/common/io/igb/igb_regs.h b/usr/src/uts/common/io/igb/igb_regs.h
index db09340c0c..588817d60b 100644
--- a/usr/src/uts/common/io/igb/igb_regs.h
+++ b/usr/src/uts/common/io/igb/igb_regs.h
@@ -1,7 +1,7 @@
/*
* CDDL HEADER START
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
@@ -22,17 +22,15 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms of the CDDL.
*/
-/* IntelVersion: 1.41 v2007-12-10_dragonlake5 */
+/* IntelVersion: 1.61 v2008-10-7 */
#ifndef _IGB_REGS_H
#define _IGB_REGS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,6 +46,7 @@ extern "C" {
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
+#define E1000_FEXT 0x0002C /* Future Extended - RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
@@ -58,7 +57,6 @@ extern "C" {
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
-#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
@@ -70,6 +68,9 @@ extern "C" {
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
+#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
+#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
#define E1000_TCTL 0x00400 /* Tx Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */
#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */
@@ -95,6 +96,12 @@ extern "C" {
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
+#define E1000_VPDDIAG 0x01060 /* VPD Diagnostic - RO */
+#define E1000_ICR_V2 0x01500 /* Interrupt Cause - new location - RC */
+#define E1000_ICS_V2 0x01504 /* Interrupt Cause Set - new location - WO */
+#define E1000_IMS_V2 0x01508 /* Interrupt Mask Set/Read - new location - RW */
+#define E1000_IMC_V2 0x0150C /* Interrupt Mask Clear - new location - WO */
+#define E1000_IAM_V2 0x01510 /* Interrupt Ack Auto Mask - new location - RW */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
@@ -108,6 +115,13 @@ extern "C" {
#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */
#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */
#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */
+#define E1000_PBDIAG 0x02458 /* Packet Buffer Diagnostic - RW */
+#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
+#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n)))
+#define E1000_RQDPC(_n) (0x0C030 + (0x40 * (_n)))
+#define E1000_TXCTL(_n) (0x0E014 + (0x40 * (_n)))
+#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n)))
+#define E1000_RQDPC(_n) (0x0C030 + (0x40 * (_n)))
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
/*
@@ -118,67 +132,75 @@ extern "C" {
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
-#define E1000_RDBAL(_n) ((_n) < 4 \
- ? (0x02800 + ((_n) * 0x100)) \
- : (0x0C000 + ((_n) * 0x40)))
-#define E1000_RDBAH(_n) ((_n) < 4 \
- ? (0x02804 + ((_n) * 0x100)) \
- : (0x0C004 + ((_n) * 0x40)))
-#define E1000_RDLEN(_n) ((_n) < 4 \
- ? (0x02808 + ((_n) * 0x100)) \
- : (0x0C008 + ((_n) * 0x40)))
-#define E1000_SRRCTL(_n) ((_n) < 4 \
- ? (0x0280C + ((_n) * 0x100)) \
- : (0x0C00C + ((_n) * 0x40)))
-#define E1000_RDH(_n) ((_n) < 4 \
- ? (0x02810 + ((_n) * 0x100)) \
- : (0x0C010 + ((_n) * 0x40)))
-#define E1000_RDT(_n) ((_n) < 4 \
- ? (0x02818 + ((_n) * 0x100)) \
- : (0x0C018 + ((_n) * 0x40)))
-#define E1000_RXDCTL(_n) ((_n) < 4 \
- ? (0x02828 + ((_n) * 0x100)) \
- : (0x0C028 + ((_n) * 0x40)))
-#define E1000_TDBAL(_n) ((_n) < 4 \
- ? (0x03800 + ((_n) * 0x100)) \
- : (0x0E000 + ((_n) * 0x40)))
-#define E1000_TDBAH(_n) ((_n) < 4 \
- ? (0x03804 + ((_n) * 0x100)) \
- : (0x0E004 + ((_n) * 0x40)))
-#define E1000_TDLEN(_n) ((_n) < 4 \
- ? (0x03808 + ((_n) * 0x100)) \
- : (0x0E008 + ((_n) * 0x40)))
-#define E1000_TDH(_n) ((_n) < 4 \
- ? (0x03810 + ((_n) * 0x100)) \
- : (0x0E010 + ((_n) * 0x40)))
-#define E1000_TDT(_n) ((_n) < 4 \
- ? (0x03818 + ((_n) * 0x100)) \
- : (0x0E018 + ((_n) * 0x40)))
-#define E1000_TXDCTL(_n) ((_n) < 4 \
- ? (0x03828 + ((_n) * 0x100)) \
- : (0x0E028 + ((_n) * 0x40)))
-#define E1000_TARC(_n) (0x03840 + (_n << 8))
-#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
-#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
-#define E1000_TDWBAL(_n) ((_n) < 4 \
- ? (0x03838 + ((_n) * 0x100)) \
- : (0x0E038 + ((_n) * 0x40)))
-#define E1000_TDWBAH(_n) ((_n) < 4 \
- ? (0x0383C + ((_n) * 0x100)) \
- : (0x0E03C + ((_n) * 0x40)))
+#define E1000_RDBAL(_n) ((_n) < 4 ? \
+ (0x02800 + ((_n) * 0x100)) : \
+ (0x0C000 + ((_n) * 0x40)))
+#define E1000_RDBAH(_n) ((_n) < 4 ? \
+ (0x02804 + ((_n) * 0x100)) : \
+ (0x0C004 + ((_n) * 0x40)))
+#define E1000_RDLEN(_n) ((_n) < 4 ? \
+ (0x02808 + ((_n) * 0x100)) : \
+ (0x0C008 + ((_n) * 0x40)))
+#define E1000_SRRCTL(_n) ((_n) < 4 ? \
+ (0x0280C + ((_n) * 0x100)) : \
+ (0x0C00C + ((_n) * 0x40)))
+#define E1000_RDH(_n) ((_n) < 4 ? \
+ (0x02810 + ((_n) * 0x100)) : \
+ (0x0C010 + ((_n) * 0x40)))
+#define E1000_RDT(_n) ((_n) < 4 ? \
+ (0x02818 + ((_n) * 0x100)) : \
+ (0x0C018 + ((_n) * 0x40)))
+#define E1000_RXDCTL(_n) ((_n) < 4 ? \
+ (0x02828 + ((_n) * 0x100)) : \
+ (0x0C028 + ((_n) * 0x40)))
+#define E1000_TDBAL(_n) ((_n) < 4 ? \
+ (0x03800 + ((_n) * 0x100)) : \
+ (0x0E000 + ((_n) * 0x40)))
+#define E1000_TDBAH(_n) ((_n) < 4 ? \
+ (0x03804 + ((_n) * 0x100)) : \
+ (0x0E004 + ((_n) * 0x40)))
+#define E1000_TDLEN(_n) ((_n) < 4 ? \
+ (0x03808 + ((_n) * 0x100)) : \
+ (0x0E008 + ((_n) * 0x40)))
+#define E1000_TDH(_n) ((_n) < 4 ? \
+ (0x03810 + ((_n) * 0x100)) : \
+ (0x0E010 + ((_n) * 0x40)))
+#define E1000_TDT(_n) ((_n) < 4 ? \
+ (0x03818 + ((_n) * 0x100)) : \
+ (0x0E018 + ((_n) * 0x40)))
+#define E1000_TXDCTL(_n) ((_n) < 4 ? \
+ (0x03828 + ((_n) * 0x100)) : \
+ (0x0E028 + ((_n) * 0x40)))
+#define E1000_TARC(_n) (0x03840 + (_n << 8))
+#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
+#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#define E1000_TDWBAL(_n) ((_n) < 4 ? \
+ (0x03838 + ((_n) * 0x100)) : \
+ (0x0E038 + ((_n) * 0x40)))
+#define E1000_TDWBAH(_n) ((_n) < 4 ? \
+ (0x0383C + ((_n) * 0x100)) : \
+ (0x0E03C + ((_n) * 0x40)))
#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
-#define E1000_RAL(_i) (0x05400 + ((_i) * 8))
-#define E1000_RAH(_i) (0x05404 + ((_i) * 8))
+#define E1000_RAL(_i) (((_i) <= 15) ? \
+ (0x05400 + ((_i) * 8)) : \
+ (0x054E0 + ((_i - 16) * 8)))
+#define E1000_RAH(_i) (((_i) <= 15) ? \
+ (0x05404 + ((_i) * 8)) : \
+ (0x054E4 + ((_i - 16) * 8)))
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8))
#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8))
#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8))
+#define E1000_PBSLAC 0x03100 /* Packet Buffer Slave Access Control */
+/* Packet Buffer DWORD (_n) */
+#define E1000_PBSLAD(_n) (0x03110 + (0x4 * (_n)))
+#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */
@@ -190,6 +212,9 @@ extern "C" {
#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */
#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */
+#define E1000_DTXTCPFLGL 0x0359C /* DMA Tx Control flag low - RW */
+#define E1000_DTXTCPFLGH 0x035A0 /* DMA Tx Control flag high - RW */
+#define E1000_DTXMXSZRQ 0x03540 /* DMA Tx Max Total Allow Size Requests - RW */
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
@@ -252,21 +277,94 @@ extern "C" {
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
-/* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXPTC 0x04104
-/* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICRXATC 0x04108
-/* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXPTC 0x0410C
-/* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXATC 0x04110
+#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Pkt Timer Expire Count */
+#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Abs Timer Expire Count */
+#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Pkt Timer Expire Count */
+#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Abs Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-/* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICTXQMTC 0x0411C
-/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXDMTC 0x04120
+#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Min Thresh Count */
+#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Desc Min Thresh Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
+/* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
+#define E1000_LSECTXUT 0x04300
+/* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
+#define E1000_LSECTXPKTE 0x04304
+/* LinkSec Protected Tx Packet Count - OutPktsProtected */
+#define E1000_LSECTXPKTP 0x04308
+/* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */
+#define E1000_LSECTXOCTE 0x0430C
+/* LinkSec Protected Tx Octets Count - OutOctetsProtected */
+#define E1000_LSECTXOCTP 0x04310
+/* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */
+#define E1000_LSECRXUT 0x04314
+/* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */
+#define E1000_LSECRXOCTD 0x0431C
+/* LinkSec Rx Octets Validated - InOctetsValidated */
+#define E1000_LSECRXOCTV 0x04320
+/* LinkSec Rx Bad Tag - InPktsBadTag */
+#define E1000_LSECRXBAD 0x04324
+/* LinkSec Rx Packet No SCI Count - InPktsNoSci */
+#define E1000_LSECRXNOSCI 0x04328
+/* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */
+#define E1000_LSECRXUNSCI 0x0432C
+/* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */
+#define E1000_LSECRXUNCH 0x04330
+/* LinkSec Rx Delayed Packet Count - InPktsDelayed */
+#define E1000_LSECRXDELAY 0x04340
+/* LinkSec Rx Late Packets Count - InPktsLate */
+#define E1000_LSECRXLATE 0x04350
+/* LinkSec Rx Packet OK Count - InPktsOk */
+#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n)))
+/* LinkSec Rx Invalid Count - InPktsInvalid */
+#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n)))
+/* LinkSec Rx Not Valid Count - InPktsNotValid */
+#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n)))
+/* LinkSec Rx Unused SA Count - InPktsUnusedSa */
+#define E1000_LSECRXUNSA 0x043C0
+/* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */
+#define E1000_LSECRXNUSA 0x043D0
+/* LinkSec Tx Capabilities Register - RO */
+#define E1000_LSECTXCAP 0x0B000
+/* LinkSec Rx Capabilities Register - RO */
+#define E1000_LSECRXCAP 0x0B300
+#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */
+#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */
+#define E1000_LSECTXSCL 0x0B008 /* LinkSec Tx SCI Low - RW */
+#define E1000_LSECTXSCH 0x0B00C /* LinkSec Tx SCI High - RW */
+#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */
+#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */
+#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */
+#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */
+#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */
+/* LinkSec Tx 128-bit Key 0 - WO */
+#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n)))
+/* LinkSec Tx 128-bit Key 1 - WO */
+#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
+/* LinkSec Rx SAs - RW */
+#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n)))
+/* LinkSec Rx SAs - RW */
+#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n)))
+/*
+ * LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
+ * key - RW.
+ */
+#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
+
+#define E1000_SSVPC 0x041A0 /* Switch Security Violation Packet Count */
+#define E1000_IPSCTRL 0xB430 /* IpSec Control Register */
+#define E1000_IPSRXCMD 0x0B408 /* IPSec Rx Command Register - RW */
+#define E1000_IPSRXIDX 0x0B400 /* IPSec Rx Index - RW */
+/* IPSec Rx IPv4/v6 Address - RW */
+#define E1000_IPSRXIPADDR(_n) (0x0B420+ (0x04 * (_n)))
+/* IPSec Rx 128-bit Key - RW */
+#define E1000_IPSRXKEY(_n) (0x0B410 + (0x04 * (_n)))
+#define E1000_IPSRXSALT 0x0B404 /* IPSec Rx Salt - RW */
+#define E1000_IPSRXSPI 0x0B40C /* IPSec Rx SPI - RW */
+/* IPSec Tx 128-bit Key - RW */
+#define E1000_IPSTXKEY(_n) (0x0B460 + (0x04 * (_n)))
+#define E1000_IPSTXSALT 0x0B454 /* IPSec Tx Salt - RW */
+#define E1000_IPSTXIDX 0x0B450 /* IPSec Tx SA IDX - RW */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
@@ -287,17 +385,17 @@ extern "C" {
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
-/* Link Partner Ability Next Page - RW */
-#define E1000_PCS_LPABNP 0x04224
-/* 1GSTAT Code Violation Packet Count - RW */
-#define E1000_1GSTAT_RCV 0x04228
+#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
+#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control */
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
+/* 2nd half of receive address array - RW Array */
+#define E1000_RA2 0x054E0
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
+#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
@@ -314,6 +412,10 @@ extern "C" {
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
+/* Flexible Host Filter Table */
+#define E1000_FHFT(_n) (0x09000 + (_n * 0x100))
+/* Ext Flexible Host Filter Table */
+#define E1000_FHFT_EXT(_n) (0x09A00 + (_n * 0x100))
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
@@ -335,7 +437,7 @@ extern "C" {
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
+#define E1000_HICR 0x08F00 /* Host Interface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
@@ -361,6 +463,76 @@ extern "C" {
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4))
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
+/* VT Registers */
+#define E1000_SWPBS 0x03004 /* Switch Packet Buffer Size - RW */
+#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
+#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
+#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
+#define E1000_VFRE 0x00C8C /* VF Receive Enables */
+#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
+#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
+#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
+#define E1000_VLVF 0x05D00 /* VLAN Virtual Machine Filter - RW */
+#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
+#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
+#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
+#define E1000_VMRCTL 0X05D80 /* Virtual Mirror Rule Control */
+/* These act per VF so an array friendly macro is used */
+#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
+#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
+#define E1000_VFVMBMEM(_n) (0x00800 + (_n))
+#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
+
+/* Filtering Registers */
+#define E1000_SAQF(_n) (0x05980 + (4 * (_n))) /* Source Address Queue Fltr */
+#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
+#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */
+#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
+#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
+#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+
+#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */
+#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */
+#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
+#define E1000_RTRUP2TC 0x05AC4 /* Rx User Priority to Traffic Class */
+#define E1000_RTTUP2TC 0x0418 /* Transmit User Priority to Traffic Class */
+/* Tx Desc plane TC Rate-scheduler config */
+#define E1000_RTTDTCRC(_n) (0x3610 + ((_n) * 4))
+/* Tx Packet plane TC Rate-Scheduler Config */
+#define E1000_RTTPTCRC(_n) (0x3480 + ((_n) * 4))
+/* Rx Packet plane TC Rate-Scheduler Config */
+#define E1000_RTRPTCRC(_n) (0x2480 + ((_n) * 4))
+/* Tx Desc Plane TC Rate-Scheduler Status */
+#define E1000_RTTDTCRS(_n) (0x3630 + ((_n) * 4))
+/* Tx Desc Plane TC Rate-Scheduler MMW */
+#define E1000_RTTDTCRM(_n) (0x3650 + ((_n) * 4))
+/* Tx Packet plane TC Rate-Scheduler Status */
+#define E1000_RTTPTCRS(_n) (0x34A0 + ((_n) * 4))
+/* Tx Packet plane TC Rate-scheduler MMW */
+#define E1000_RTTPTCRM(_n) (0x34C0 + ((_n) * 4))
+/* Rx Packet plane TC Rate-Scheduler Status */
+#define E1000_RTRPTCRS(_n) (0x24A0 + ((_n) * 4))
+/* Rx Packet plane TC Rate-Scheduler MMW */
+#define E1000_RTRPTCRM(_n) (0x24C0 + ((_n) * 4))
+/* Tx Desc plane VM Rate-Scheduler MMW */
+#define E1000_RTTDVMRM(_n) (0x3670 + ((_n) * 4))
+/* Tx BCN Rate-Scheduler MMW */
+#define E1000_RTTBCNRM(_n) (0x3690 + ((_n) * 4))
+#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select */
+#define E1000_RTTDVMRC 0x3608 /* Tx Desc Plane VM Rate-Scheduler Config */
+#define E1000_RTTDVMRS 0x360C /* Tx Desc Plane VM Rate-Scheduler Status */
+#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config */
+#define E1000_RTTBCNRS 0x36B4 /* Tx BCN Rate-Scheduler Status */
+#define E1000_RTTBCNCR 0xB200 /* Tx BCN Control Register */
+#define E1000_RTTBCNTG 0x35A4 /* Tx BCN Tagging */
+#define E1000_RTTBCNCP 0xB208 /* Tx BCN Congestion point */
+#define E1000_RTRBCNCR 0xB20C /* Rx BCN Control Register */
+#define E1000_RTTBCNRD 0x36B8 /* Tx BCN Rate Drift */
+#define E1000_PFCTOP 0x1080 /* Priority Flow Control Type and Opcode */
+#define E1000_RTTBCNIDX 0xB204 /* Tx BCN Congestion Point */
+#define E1000_RTTBCNACH 0x0B214 /* Tx BCN Control High */
+#define E1000_RTTBCNACL 0x0B210 /* Tx BCN Control Low */
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/io/igb/igb_rx.c b/usr/src/uts/common/io/igb/igb_rx.c
index acf15ed35c..d1f6368a8d 100644
--- a/usr/src/uts/common/io/igb/igb_rx.c
+++ b/usr/src/uts/common/io/igb/igb_rx.c
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,12 +22,8 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
#include "igb_sw.h"
@@ -68,13 +66,9 @@ igb_rx_recycle(caddr_t arg)
* Using the recycled data buffer to generate a new mblk
*/
recycle_rcb->mp = desballoc((unsigned char *)
- (recycle_rcb->rx_buf.address - IPHDR_ALIGN_ROOM),
- (recycle_rcb->rx_buf.size + IPHDR_ALIGN_ROOM),
+ recycle_rcb->rx_buf.address,
+ recycle_rcb->rx_buf.size,
0, &recycle_rcb->free_rtn);
- if (recycle_rcb->mp != NULL) {
- recycle_rcb->mp->b_rptr += IPHDR_ALIGN_ROOM;
- recycle_rcb->mp->b_wptr += IPHDR_ALIGN_ROOM;
- }
/*
* Put the recycled rx control block into free list
@@ -169,8 +163,8 @@ igb_rx_bind(igb_rx_ring_t *rx_ring, uint32_t index, uint32_t pkt_len)
*/
if (current_rcb->mp == NULL) {
current_rcb->mp = desballoc((unsigned char *)
- (current_rcb->rx_buf.address - IPHDR_ALIGN_ROOM),
- (current_rcb->rx_buf.size + IPHDR_ALIGN_ROOM),
+ current_rcb->rx_buf.address,
+ current_rcb->rx_buf.size,
0, &current_rcb->free_rtn);
/*
* If it is failed to built a mblk using the current
diff --git a/usr/src/uts/common/io/igb/igb_sw.h b/usr/src/uts/common/io/igb/igb_sw.h
index a69ba3bb77..4cd1045c16 100644
--- a/usr/src/uts/common/io/igb/igb_sw.h
+++ b/usr/src/uts/common/io/igb/igb_sw.h
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,12 +22,8 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
#ifndef _IGB_SW_H
@@ -88,16 +86,25 @@ extern "C" {
#define IGB_INTR_MSI 2
#define IGB_INTR_LEGACY 3
+#define IGB_ADAPTER_REGSET 1 /* mapping adapter registers */
+#define IGB_ADAPTER_MSIXTAB 4 /* mapping msi-x table */
+
#define IGB_NO_POLL -1
#define IGB_NO_FREE_SLOT -1
#define MAX_NUM_UNICAST_ADDRESSES E1000_RAR_ENTRIES
#define MAX_NUM_MULTICAST_ADDRESSES 256
-#define MAX_NUM_EITR 10
#define MAX_COOKIE 16
#define MIN_NUM_TX_DESC 2
/*
+ * Number of settings for interrupt throttle rate (ITR). There is one of
+ * these per msi-x vector and it needs to be the maximum of all silicon
+ * types supported by this driver.
+ */
+#define MAX_NUM_EITR 25
+
+/*
* Maximum values for user configurable parameters
*/
#define MAX_TX_RING_SIZE 4096
@@ -110,7 +117,6 @@ extern "C" {
#define MAX_RX_INTR_ABS_DELAY 65535
#define MAX_TX_INTR_DELAY 65535
#define MAX_TX_INTR_ABS_DELAY 65535
-#define MAX_INTR_THROTTLING 65535
#define MAX_RX_COPY_THRESHOLD 9216
#define MAX_TX_COPY_THRESHOLD 9216
@@ -131,7 +137,6 @@ extern "C" {
#define MIN_RX_INTR_ABS_DELAY 0
#define MIN_TX_INTR_DELAY 0
#define MIN_TX_INTR_ABS_DELAY 0
-#define MIN_INTR_THROTTLING 0
#define MIN_RX_COPY_THRESHOLD 0
#define MIN_TX_COPY_THRESHOLD 0
#define MIN_TX_RECYCLE_THRESHOLD MIN_NUM_TX_DESC
@@ -141,8 +146,6 @@ extern "C" {
/*
* Default values for user configurable parameters
*/
-#define DEFAULT_TX_QUEUE_NUM 4
-#define DEFAULT_RX_QUEUE_NUM 4
#define DEFAULT_TX_RING_SIZE 512
#define DEFAULT_RX_RING_SIZE 512
#define DEFAULT_RX_GROUP_NUM 1
@@ -153,7 +156,6 @@ extern "C" {
#define DEFAULT_RX_INTR_ABS_DELAY 0
#define DEFAULT_TX_INTR_DELAY 300
#define DEFAULT_TX_INTR_ABS_DELAY 0
-#define DEFAULT_INTR_THROTTLING 200 /* In unit of 256 nsec */
#define DEFAULT_RX_COPY_THRESHOLD 128
#define DEFAULT_TX_COPY_THRESHOLD 512
#define DEFAULT_TX_RECYCLE_THRESHOLD MAX_COOKIE
@@ -337,6 +339,33 @@ typedef struct link_list {
DDI_PROP_DONTPASS, (n), -1)
+/* capability/feature flags */
+#define IGB_FLAG_HAS_DCA (1 << 0) /* has Direct Cache Access */
+#define IGB_FLAG_VMDQ_POOL (1 << 1) /* has vmdq capability */
+#define IGB_FLAG_NEED_CTX_IDX (1 << 2) /* context descriptor needs index */
+
+/* function pointer for nic-specific functions */
+typedef void (*igb_nic_func_t)(struct igb *);
+
+/* adapter-specific info for each supported device type */
+typedef struct adapter_info {
+ /* limits */
+ uint32_t max_rx_que_num; /* maximum number of rx queues */
+ uint32_t min_rx_que_num; /* minimum number of rx queues */
+ uint32_t def_rx_que_num; /* default number of rx queues */
+ uint32_t max_tx_que_num; /* maximum number of tx queues */
+ uint32_t min_tx_que_num; /* minimum number of tx queues */
+ uint32_t def_tx_que_num; /* default number of tx queues */
+ uint32_t max_intr_throttle; /* maximum interrupt throttle */
+ uint32_t min_intr_throttle; /* minimum interrupt throttle */
+ uint32_t def_intr_throttle; /* default interrupt throttle */
+ /* function pointers */
+ igb_nic_func_t enable_intr; /* enable adapter interrupts */
+ igb_nic_func_t setup_msix; /* set up msi-x vectors */
+ /* capabilities */
+ uint32_t flags; /* capability flags */
+} adapter_info_t;
+
/*
* Named Data (ND) Parameter Management Structure
*/
@@ -620,6 +649,8 @@ typedef struct igb {
struct e1000_hw hw;
struct igb_osdep osdep;
+ adapter_info_t *capab; /* adapter capabilities */
+
uint32_t igb_state;
link_state_t link_state;
uint32_t link_speed;
@@ -780,6 +811,9 @@ typedef struct igb_stat {
* Function prototypes in e1000_osdep.c
*/
void e1000_enable_pciex_master(struct e1000_hw *);
+void e1000_rar_clear(struct e1000_hw *hw, uint32_t);
+void e1000_rar_set_vmdq(struct e1000_hw *hw, const uint8_t *, uint32_t,
+ uint32_t, uint8_t);
/*
* Function prototypes in igb_buf.c
diff --git a/usr/src/uts/common/io/igb/igb_tx.c b/usr/src/uts/common/io/igb/igb_tx.c
index 7b43bbad97..5b7883435e 100644
--- a/usr/src/uts/common/io/igb/igb_tx.c
+++ b/usr/src/uts/common/io/igb/igb_tx.c
@@ -1,17 +1,19 @@
/*
* CDDL HEADER START
*
+ * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
+ * You can obtain a copy of the license at:
+ * http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * When using or redistributing this file, you may do so under the
+ * License only. No other modification of this header is permitted.
+ *
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
@@ -20,12 +22,8 @@
*/
/*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms of the CDDL.
*/
#include "igb_sw.h"
@@ -682,6 +680,7 @@ igb_tx_fill_ring(igb_tx_ring_t *tx_ring, link_list_t *pending_list,
union e1000_adv_tx_desc *tbd, *first_tbd;
tx_control_block_t *tcb, *first_tcb;
uint32_t hcksum_flags;
+ uint32_t pay_len;
int i;
igb_t *igb = tx_ring->igb;
@@ -692,6 +691,7 @@ igb_tx_fill_ring(igb_tx_ring_t *tx_ring, link_list_t *pending_list,
first_tcb = NULL;
desc_num = 0;
hcksum_flags = 0;
+ pay_len = 0;
load_context = B_FALSE;
/*
@@ -758,10 +758,13 @@ igb_tx_fill_ring(igb_tx_ring_t *tx_ring, link_list_t *pending_list,
tbd->read.cmd_type_len = tcb->desc[i].length;
tbd->read.cmd_type_len |= E1000_ADVTXD_DCMD_RS |
- E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_DATA;
+ E1000_ADVTXD_DCMD_DEXT | E1000_ADVTXD_DTYP_DATA |
+ E1000_ADVTXD_DCMD_IFCS;
tbd->read.olinfo_status = 0;
+ pay_len += tcb->desc[i].length;
+
index = NEXT_INDEX(index, 1, tx_ring->ring_size);
desc_num++;
}
@@ -788,9 +791,14 @@ igb_tx_fill_ring(igb_tx_ring_t *tx_ring, link_list_t *pending_list,
/*
* The Insert Ethernet CRC (IFCS) bit and the checksum fields are only
* valid in the first descriptor of the packet.
+ * 82576 also requires the payload length setting even without TSO
*/
ASSERT(first_tbd != NULL);
first_tbd->read.cmd_type_len |= E1000_ADVTXD_DCMD_IFCS;
+ if (hw->mac.type == e1000_82576) {
+ first_tbd->read.olinfo_status =
+ (pay_len << E1000_ADVTXD_PAYLEN_SHIFT);
+ }
/* Set hardware checksum bits */
if (hcksum_flags != 0) {