Author: modeenf Date: 2011-05-29 21:27:05 +0200 (Sun, 29 May 2011) New Revision: 41815 Changeset: https://dev.haiku-os.org/changeset/41815 Added: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mbx.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_vf.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_lem.h Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/Jamfile haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82543.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82571.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82575.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_api.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_defines.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_hw.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_ich8lan.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_mac.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_manage.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_nvm.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_osdep.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_phy.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_regs.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_em.h haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.c haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/if_igb.h Log: Hope I fix more than I breake with this update of ipro1000 it's taken from freebsd driver e1000 r221505 This include alot of cards (including my HP) I had to "remove" som parts. led was the easiest part. All code shoulc have haiku in them The part below was perhaps needed but I could not fix the error that whas showing (located in if_em.c) aslo it works as is on my HP 8540. static int em_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) { struct adapter *adapter; u_int val; adapter = oidp->oid_arg1; val = E1000_READ_REG(&adapter->hw, oidp->oid_arg2); return (sysctl_handle_int(oidp, &val, 0, req)); } Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/Jamfile =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/Jamfile 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/Jamfile 2011-05-29 19:27:05 UTC (rev 41815) @@ -21,11 +21,13 @@ e1000_ich8lan.c e1000_mac.c e1000_manage.c + e1000_mbx.c e1000_nvm.c e1000_osdep.c e1000_phy.c + e1000_vf.c if_em.c - + glue.c : libfreebsd_network.a ; Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/LICENSE 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ -$FreeBSD: src/sys/dev/e1000/LICENSE,v 1.1.2.1 2008/08/11 18:33:10 jfv Exp $ +$FreeBSD$ - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/README 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,4 +1,4 @@ -$FreeBSD: src/sys/dev/e1000/README,v 1.1.2.1 2008/08/11 18:33:10 jfv Exp $ +$FreeBSD$ FreeBSD* Driver for Intel Network Connection ============================================= Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.c 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_80003es2lan.c,v 1.1.2.2 2008/12/01 07:13:52 jfv Exp $*/ +/*$FreeBSD$*/ /* * 80003ES2LAN Gigabit Ethernet Controller (Copper) @@ -43,9 +43,7 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); -static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw); static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); -static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, @@ -84,8 +82,8 @@ * with a lower bound at "index" and the upper bound at * "index + 5". */ -static const u16 e1000_gg82563_cable_length_table[] = - { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; +static const u16 e1000_gg82563_cable_length_table[] = { + 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ (sizeof(e1000_gg82563_cable_length_table) / \ sizeof(e1000_gg82563_cable_length_table[0])) @@ -173,7 +171,7 @@ break; } - nvm->type = e1000_nvm_eeprom_spi; + nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); @@ -208,17 +206,22 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_80003es2lan"); - /* Set media type */ + /* Set media type and media-dependent function pointers */ switch (hw->device_id) { case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: hw->phy.media_type = e1000_media_type_internal_serdes; + mac->ops.check_for_link = e1000_check_for_serdes_link_generic; + mac->ops.setup_physical_interface = + e1000_setup_fiber_serdes_link_generic; break; default: hw->phy.media_type = e1000_media_type_copper; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; + mac->ops.setup_physical_interface = + e1000_setup_copper_link_80003es2lan; break; } @@ -228,10 +231,14 @@ mac->rar_entry_count = E1000_RAR_ENTRIES; /* Set if part includes ASF firmware */ mac->asf_firmware_present = TRUE; - /* Set if manageability features are enabled. */ + /* FWSM register */ + mac->has_fwsm = TRUE; + /* ARC supported; valid only if manageability features are enabled. */ mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) ? TRUE : FALSE; + /* Adaptive IFS not supported */ + mac->adaptive_ifs = FALSE; /* Function pointers */ @@ -243,27 +250,6 @@ mac->ops.init_hw = e1000_init_hw_80003es2lan; /* link setup */ mac->ops.setup_link = e1000_setup_link_generic; - /* physical interface link setup */ - mac->ops.setup_physical_interface = - (hw->phy.media_type == e1000_media_type_copper) - ? e1000_setup_copper_link_80003es2lan - : e1000_setup_fiber_serdes_link_generic; - /* check for link */ - switch (hw->phy.media_type) { - case e1000_media_type_copper: - mac->ops.check_for_link = e1000_check_for_copper_link_generic; - break; - case e1000_media_type_fiber: - mac->ops.check_for_link = e1000_check_for_fiber_link_generic; - break; - case e1000_media_type_internal_serdes: - mac->ops.check_for_link = e1000_check_for_serdes_link_generic; - break; - default: - ret_val = -E1000_ERR_CONFIG; - goto out; - break; - } /* check management mode */ mac->ops.check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ @@ -272,10 +258,10 @@ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; + /* ID LED init */ + mac->ops.id_led_init = e1000_id_led_init_generic; /* blink LED */ mac->ops.blink_led = e1000_blink_led_generic; /* setup LED */ @@ -290,8 +276,10 @@ /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; -out: - return ret_val; + /* set lan id for port to determine which phy lock to use */ + hw->mac.ops.set_lan_id(hw); + + return E1000_SUCCESS; } /** @@ -307,7 +295,6 @@ hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; - e1000_get_bus_info_pcie_generic(hw); } /** @@ -342,7 +329,6 @@ e1000_release_swfw_sync_80003es2lan(hw, mask); } - /** * e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register * @hw: pointer to the HW structure @@ -532,28 +518,36 @@ goto out; } - /* - * The "ready" bit in the MDIC register may be incorrectly set - * before the device has completed the "Page Select" MDI - * transaction. So we wait 200us after each MDI command... - */ - usec_delay(200); + if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { + /* + * The "ready" bit in the MDIC register may be incorrectly set + * before the device has completed the "Page Select" MDI + * transaction. So we wait 200us after each MDI command... + */ + usec_delay(200); - /* ...and verify the command was successful. */ - ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); + /* ...and verify the command was successful. */ + ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); - if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; - e1000_release_phy_80003es2lan(hw); - goto out; - } + if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { + ret_val = -E1000_ERR_PHY; + e1000_release_phy_80003es2lan(hw); + goto out; + } - usec_delay(200); + usec_delay(200); - ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + ret_val = e1000_read_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); - usec_delay(200); + usec_delay(200); + } else { + ret_val = e1000_read_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); + } + e1000_release_phy_80003es2lan(hw); out: @@ -599,29 +593,36 @@ goto out; } + if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) { + /* + * The "ready" bit in the MDIC register may be incorrectly set + * before the device has completed the "Page Select" MDI + * transaction. So we wait 200us after each MDI command... + */ + usec_delay(200); - /* - * The "ready" bit in the MDIC register may be incorrectly set - * before the device has completed the "Page Select" MDI - * transaction. So we wait 200us after each MDI command... - */ - usec_delay(200); + /* ...and verify the command was successful. */ + ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); - /* ...and verify the command was successful. */ - ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); + if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { + ret_val = -E1000_ERR_PHY; + e1000_release_phy_80003es2lan(hw); + goto out; + } - if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { - ret_val = -E1000_ERR_PHY; - e1000_release_phy_80003es2lan(hw); - goto out; - } + usec_delay(200); - usec_delay(200); + ret_val = e1000_write_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); - ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); + usec_delay(200); + } else { + ret_val = e1000_write_phy_reg_mdic(hw, + MAX_PHY_REG_ADDRESS & offset, + data); + } - usec_delay(200); e1000_release_phy_80003es2lan(hw); out: @@ -802,17 +803,16 @@ index = phy_data & GG82563_DSPD_CABLE_LENGTH; - if (index < GG82563_CABLE_LENGTH_TABLE_SIZE + 5) { - phy->min_cable_length = e1000_gg82563_cable_length_table[index]; - phy->max_cable_length = - e1000_gg82563_cable_length_table[index+5]; - - phy->cable_length = (phy->min_cable_length + - phy->max_cable_length) / 2; - } else { - ret_val = E1000_ERR_PHY; + if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) { + ret_val = -E1000_ERR_PHY; + goto out; } + phy->min_cable_length = e1000_gg82563_cable_length_table[index]; + phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5]; + + phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; + out: return ret_val; } @@ -854,7 +854,7 @@ **/ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { - u32 ctrl, icr; + u32 ctrl; s32 ret_val; DEBUGFUNC("e1000_reset_hw_80003es2lan"); @@ -890,9 +890,9 @@ /* Clear any pending interrupt events. */ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); - icr = E1000_READ_REG(hw, E1000_ICR); + E1000_READ_REG(hw, E1000_ICR); - e1000_check_alt_mac_addr_generic(hw); + ret_val = e1000_check_alt_mac_addr_generic(hw); out: return ret_val; @@ -909,6 +909,7 @@ struct e1000_mac_info *mac = &hw->mac; u32 reg_data; s32 ret_val; + u16 kum_reg_data; u16 i; DEBUGFUNC("e1000_init_hw_80003es2lan"); @@ -916,11 +917,10 @@ e1000_initialize_hw_bits_80003es2lan(hw); /* Initialize identification LED */ - ret_val = e1000_id_led_init_generic(hw); - if (ret_val) { + ret_val = mac->ops.id_led_init(hw); + if (ret_val) DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ - } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -937,6 +937,13 @@ /* Setup link and flow control */ ret_val = mac->ops.setup_link(hw); + /* Disable IBIST slave mode (far-end loopback) */ + e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + &kum_reg_data); + kum_reg_data |= E1000_KMRNCTRLSTA_IBIST_DISABLE; + e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_INBAND_PARAM, + kum_reg_data); + /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | @@ -970,6 +977,19 @@ reg_data &= ~0x00100000; E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); + /* default to TRUE to enable the MDIC W/A */ + hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE; + + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, + E1000_KMRNCTRLSTA_OFFSET >> + E1000_KMRNCTRLSTA_OFFSET_SHIFT, + &i); + if (!ret_val) { + if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) == + E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO) + hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE; + } + /* * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link @@ -1036,77 +1056,78 @@ DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); - if (!phy->reset_disable) { - ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - &data); - if (ret_val) - goto out; + if (phy->reset_disable) + goto skip_reset; - data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ - data |= GG82563_MSCR_TX_CLK_1000MBPS_25; + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + &data); + if (ret_val) + goto out; - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, - data); - if (ret_val) - goto out; + data |= GG82563_MSCR_ASSERT_CRS_ON_TX; + /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ + data |= GG82563_MSCR_TX_CLK_1000MBPS_25; - /* - * Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); - if (ret_val) - goto out; + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + data); + if (ret_val) + goto out; - data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; + /* + * Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); + if (ret_val) + goto out; - switch (phy->mdix) { - case 1: - data |= GG82563_PSCR_CROSSOVER_MODE_MDI; - break; - case 2: - data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; - break; - case 0: - default: - data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; - break; - } + data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; - /* - * Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - if (phy->disable_polarity_correction) - data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; + switch (phy->mdix) { + case 1: + data |= GG82563_PSCR_CROSSOVER_MODE_MDI; + break; + case 2: + data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; + break; + case 0: + default: + data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; + break; + } - ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); - if (ret_val) - goto out; + /* + * Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; + if (phy->disable_polarity_correction) + data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - /* SW Reset the PHY so all changes take effect */ - ret_val = hw->phy.ops.commit(hw); - if (ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - goto out; - } + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); + if (ret_val) + goto out; + /* SW Reset the PHY so all changes take effect */ + ret_val = hw->phy.ops.commit(hw); + if (ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + goto out; } +skip_reset: /* Bypass Rx and Tx FIFO's */ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, - E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, - E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | - E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); + E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, + E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | + E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); if (ret_val) goto out; @@ -1147,22 +1168,19 @@ if (!(hw->mac.ops.check_mng_mode(hw))) { /* Enable Electrical Idle on the PHY */ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; - ret_val = hw->phy.ops.write_reg(hw, - GG82563_PHY_PWR_MGMT_CTRL, + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, data); if (ret_val) goto out; - ret_val = hw->phy.ops.read_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, - &data); - if (ret_val) - goto out; + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, + &data); + if (ret_val) + goto out; + data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = hw->phy.ops.write_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, data); - if (ret_val) goto out; } @@ -1261,7 +1279,6 @@ DEBUGFUNC("e1000_configure_on_link_up"); if (hw->phy.media_type == e1000_media_type_copper) { - ret_val = e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex); @@ -1308,7 +1325,6 @@ tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; E1000_WRITE_REG(hw, E1000_TIPG, tipg); - do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); @@ -1362,7 +1378,6 @@ tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; E1000_WRITE_REG(hw, E1000_TIPG, tipg); - do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); @@ -1393,7 +1408,8 @@ * using the kumeran interface. The information retrieved is stored in data. * Release the semaphore before exiting. **/ -s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, + u16 *data) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; @@ -1429,7 +1445,8 @@ * at the offset using the kumeran interface. Release semaphore * before exiting. **/ -s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data) +static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, + u16 data) { u32 kmrnctrlsta; s32 ret_val = E1000_SUCCESS; @@ -1461,9 +1478,19 @@ s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_mac_addr_80003es2lan"); - if (e1000_check_alt_mac_addr_generic(hw)) - ret_val = e1000_read_mac_addr_generic(hw); + /* + * If there's an alternate MAC address place it in RAR0 + * so that it will override the Si installed default perm + * address. + */ + ret_val = e1000_check_alt_mac_addr_generic(hw); + if (ret_val) + goto out; + + ret_val = e1000_read_mac_addr_generic(hw); + +out: return ret_val; } Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_80003es2lan.h 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ -/******************************************************************************* +/****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -29,10 +29,9 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_80003es2lan.h,v 1.1.2.1 2008/08/11 18:33:10 jfv Exp $*/ +******************************************************************************/ +/*$FreeBSD$*/ - #ifndef _E1000_80003ES2LAN_H_ #define _E1000_80003ES2LAN_H_ @@ -49,6 +48,9 @@ #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 #define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 +#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C +#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004 + #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82540.c 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_82540.c,v 1.1.2.2 2008/12/01 07:13:52 jfv Exp $*/ +/*$FreeBSD$*/ /* * 82540EM Gigabit Ethernet Controller @@ -57,6 +57,7 @@ static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw); static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82540(struct e1000_hw *hw); /** * e1000_init_phy_params_82540 - Init PHY func ptrs. @@ -227,8 +228,10 @@ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82540; + /* ID LED init */ + mac->ops.id_led_init = e1000_id_led_init_generic; /* setup LED */ mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ @@ -266,7 +269,7 @@ **/ static s32 e1000_reset_hw_82540(struct e1000_hw *hw) { - u32 ctrl, icr, manc; + u32 ctrl, manc; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_reset_hw_82540"); @@ -311,7 +314,7 @@ E1000_WRITE_REG(hw, E1000_MANC, manc); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); - icr = E1000_READ_REG(hw, E1000_ICR); + E1000_READ_REG(hw, E1000_ICR); return ret_val; } @@ -332,7 +335,7 @@ DEBUGFUNC("e1000_init_hw_82540"); /* Initialize identification LED */ - ret_val = e1000_id_led_init_generic(hw); + ret_val = mac->ops.id_led_init(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ @@ -674,3 +677,45 @@ E1000_READ_REG(hw, E1000_MGTPTC); } +/** + * e1000_read_mac_addr_82540 - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + * Since devices with two ports use the same EEPROM, we increment the + * last bit in the MAC address for the second port. + * + * This version is being used over generic because of customer issues + * with VmWare and Virtual Box when using generic. It seems in + * the emulated 82545, RAR[0] does NOT have a valid address after a + * reset, this older method works and using this breaks nothing for + * these legacy adapters. + **/ +s32 e1000_read_mac_addr_82540(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_data, i; + + DEBUGFUNC("e1000_read_mac_addr"); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = i >> 1; + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); + hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); + } + + /* Flip last bit of mac address if we're on second port */ + if (hw->bus.func == E1000_FUNC_1) + hw->mac.perm_addr[5] ^= 1; + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + +out: + return ret_val; +} Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.c 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_82541.c,v 1.1.2.2 2008/12/01 07:13:52 jfv Exp $*/ +/*$FreeBSD$*/ /* * 82541EI Gigabit Ethernet Controller @@ -59,6 +59,7 @@ static s32 e1000_setup_led_82541(struct e1000_hw *hw); static s32 e1000_cleanup_led_82541(struct e1000_hw *hw); static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82541(struct e1000_hw *hw); static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, bool link_up); static s32 e1000_phy_init_script_82541(struct e1000_hw *hw); @@ -259,8 +260,10 @@ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82541; + /* ID LED init */ + mac->ops.id_led_init = e1000_id_led_init_generic; /* setup LED */ mac->ops.setup_led = e1000_setup_led_82541; /* cleanup LED */ @@ -297,7 +300,7 @@ **/ static s32 e1000_reset_hw_82541(struct e1000_hw *hw) { - u32 ledctl, ctrl, icr, manc; + u32 ledctl, ctrl, manc; DEBUGFUNC("e1000_reset_hw_82541"); @@ -361,7 +364,7 @@ E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF); /* Clear any pending interrupt events. */ - icr = E1000_READ_REG(hw, E1000_ICR); + E1000_READ_REG(hw, E1000_ICR); return E1000_SUCCESS; } @@ -375,18 +378,26 @@ static s32 e1000_init_hw_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; u32 i, txdctl; s32 ret_val; DEBUGFUNC("e1000_init_hw_82541"); /* Initialize identification LED */ - ret_val = e1000_id_led_init_generic(hw); + ret_val = mac->ops.id_led_init(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ } + /* Storing the Speed Power Down value for later use */ + ret_val = hw->phy.ops.read_reg(hw, + IGP01E1000_GMII_FIFO, + &dev_spec->spd_default); + if (ret_val) + goto out; + /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); mac->ops.clear_vfta(hw); @@ -423,6 +434,7 @@ */ e1000_clear_hw_cntrs_82541(hw); +out: return ret_val; } @@ -1281,3 +1293,35 @@ E1000_READ_REG(hw, E1000_MGTPDC); E1000_READ_REG(hw, E1000_MGTPTC); } + +/** + * e1000_read_mac_addr_82541 - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + **/ +static s32 e1000_read_mac_addr_82541(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_data, i; + + DEBUGFUNC("e1000_read_mac_addr"); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = i >> 1; + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); + hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); + } + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + +out: + return ret_val; +} + Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82541.h 2011-05-29 19:27:05 UTC (rev 41815) @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_82541.h,v 1.1.2.1 2008/08/11 18:33:10 jfv Exp $*/ +/*$FreeBSD$*/ #ifndef _E1000_82541_H_ #define _E1000_82541_H_ Modified: haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c =================================================================== --- haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c 2011-05-29 19:12:25 UTC (rev 41814) +++ haiku/trunk/src/add-ons/kernel/drivers/network/ipro1000/dev/e1000/e1000_82542.c 2011-05-29 19:27:05 UTC (rev 41815) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2008, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ -/*$FreeBSD: src/sys/dev/e1000/e1000_82542.c,v 1.1.2.2 2008/12/01 07:13:52 jfv Exp $*/ +/*$FreeBSD$*/ /* * 82542 Gigabit Ethernet Controller @@ -49,6 +49,7 @@ static s32 e1000_led_off_82542(struct e1000_hw *hw); static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index); static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82542(struct e1000_hw *hw); /** * e1000_init_phy_params_82542 - Init PHY func ptrs. @@ -132,8 +133,8 @@ mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ mac->ops.clear_vfta = e1000_clear_vfta_generic; - /* setting MTA */ - mac->ops.mta_set = e1000_mta_set_generic; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82542; /* set RAR */ mac->ops.rar_set = e1000_rar_set_82542; /* turn on/off LED */ @@ -190,7 +191,7 @@ { struct e1000_bus_info *bus = &hw->bus; s32 ret_val = E1000_SUCCESS; - u32 ctrl, icr; + u32 ctrl; DEBUGFUNC("e1000_reset_hw_82542"); [... truncated: 33574 lines follow ...]