Mercurial > illumos > illumos-gate
changeset 10319:0355b7a83c0d
6870811 igb needs to integrate the latest Intel shared code
author | zhefeng xu - Sun Microsystems - Beijing China <Jason.Xu@Sun.COM> |
---|---|
date | Sun, 16 Aug 2009 19:52:03 +0800 |
parents | 811db323512d |
children | 35786983c32a |
files | usr/src/pkgdefs/SUNWigb/postinstall usr/src/uts/common/io/igb/igb_82575.c usr/src/uts/common/io/igb/igb_82575.h usr/src/uts/common/io/igb/igb_api.c usr/src/uts/common/io/igb/igb_api.h usr/src/uts/common/io/igb/igb_defines.h usr/src/uts/common/io/igb/igb_hw.h usr/src/uts/common/io/igb/igb_mac.c usr/src/uts/common/io/igb/igb_mac.h usr/src/uts/common/io/igb/igb_main.c usr/src/uts/common/io/igb/igb_manage.c usr/src/uts/common/io/igb/igb_manage.h usr/src/uts/common/io/igb/igb_nvm.c usr/src/uts/common/io/igb/igb_nvm.h usr/src/uts/common/io/igb/igb_osdep.c usr/src/uts/common/io/igb/igb_osdep.h usr/src/uts/common/io/igb/igb_phy.c usr/src/uts/common/io/igb/igb_phy.h usr/src/uts/common/io/igb/igb_regs.h usr/src/uts/common/io/igb/igb_sw.h |
diffstat | 20 files changed, 592 insertions(+), 487 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/pkgdefs/SUNWigb/postinstall Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/pkgdefs/SUNWigb/postinstall Sun Aug 16 19:52:03 2009 +0800 @@ -133,5 +133,7 @@ "pciex8086,10d6" "pciex8086,10e6" "pciex8086,10e7" - "pciex8086,10e8"' \ + "pciex8086,10e8" + "pciex8086,150a" + "pciex8086,150d"' \ -b "$BASEDIR" igb
--- a/usr/src/uts/common/io/igb/igb_82575.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_82575.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,13 +26,14 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.94 v2008-10-7 */ +/* IntelVersion: 1.123 v2-9-8_2009-6-12 */ /* * 82575EB Gigabit Network Connection * 82575EB Gigabit Backplane Connection * 82575GB Gigabit Network Connection * 82576 Gigabit Network Connection + * 82576 Quad Port Gigabit Mezzanine Adapter */ #include "igb_api.h" @@ -71,11 +72,8 @@ 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); -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); +static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw); /* * e1000_init_phy_params_82575 - Init PHY func ptrs. @@ -279,13 +277,15 @@ /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82575; /* multicast address update */ - mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82575; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ 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; + /* 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 */ @@ -328,11 +328,12 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw) { - u16 mask; + u16 mask = E1000_SWFW_PHY0_SM; DEBUGFUNC("e1000_acquire_phy_82575"); - mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; + if (hw->bus.func == E1000_FUNC_1) + mask = E1000_SWFW_PHY1_SM; return (e1000_acquire_swfw_sync_82575(hw, mask)); } @@ -346,11 +347,13 @@ static void e1000_release_phy_82575(struct e1000_hw *hw) { - u16 mask; + u16 mask = E1000_SWFW_PHY0_SM; DEBUGFUNC("e1000_release_phy_82575"); - mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; + if (hw->bus.func == E1000_FUNC_1) + mask = E1000_SWFW_PHY1_SM; + e1000_release_swfw_sync_82575(hw, mask); } @@ -801,7 +804,7 @@ DEBUGFUNC("e1000_get_cfg_done_82575"); - if (hw->bus.func == 1) + if (hw->bus.func == E1000_FUNC_1) mask = E1000_NVM_CFG_DONE_PORT_1; while (timeout) { @@ -868,11 +871,18 @@ /* SGMII link check is done through the PCS register. */ if ((hw->phy.media_type != e1000_media_type_copper) || - (e1000_sgmii_active_82575(hw))) + (e1000_sgmii_active_82575(hw))) { ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed, &duplex); - else + /* + * Use this flag to determine if link needs to be checked or + * not. If we have link clear the flag so that we do not + * continue to check for link. + */ + hw->mac.get_link_status = !hw->mac.serdes_has_link; + } else { ret_val = e1000_check_for_copper_link_generic(hw); + } return (ret_val); } @@ -936,103 +946,6 @@ } /* - * e1000_init_rx_addrs_82575 - Initialize receive address's - * @hw: pointer to the HW structure - * @rar_count: receive address registers - * - * 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_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count) -{ - 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); - - /* 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 * @@ -1045,13 +958,13 @@ 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)) + if (hw->phy.media_type != e1000_media_type_internal_serdes) return; - if (hw->bus.func == 0) + if (hw->bus.func == E1000_FUNC_0) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); + else if (hw->bus.func == E1000_FUNC_1) + hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); /* * If APM is not enabled in the EEPROM and management interface is @@ -1076,6 +989,48 @@ } /* + * e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback + * @hw: pointer to the HW structure + * @enable: state to enter, either enabled or disabled + * + * enables/disables L2 switch loopback functionality + */ +void +e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) +{ + u32 reg; + + reg = E1000_READ_REG(hw, E1000_DTXSWC); + if (enable) + reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; + else + reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN); + + E1000_WRITE_REG(hw, E1000_DTXSWC, reg); +} + +/* + * e1000_vmdq_set_replication_pf - enable or disable vmdq replication + * @hw: pointer to the HW structure + * @enable: state to enter, either enabled or disabled + * + * enables/disables replication of packets across multiple pools + */ +void +e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) +{ + u32 reg; + + reg = E1000_READ_REG(hw, E1000_VT_CTL); + if (enable) + reg |= E1000_VT_CTL_VM_REPL_EN; + else + reg &= ~(E1000_VT_CTL_VM_REPL_EN); + + E1000_WRITE_REG(hw, E1000_VT_CTL, reg); +} + +/* * e1000_reset_hw_82575 - Reset hardware * @hw: pointer to the HW structure * @@ -1098,6 +1053,12 @@ DEBUGOUT("PCI-E Master disable polling has failed.\n"); } + /* set the completion timeout for interface */ + ret_val = e1000_set_pcie_completion_timeout(hw); + if (ret_val) { + DEBUGOUT("PCI-E Set completion timeout has failed.\n"); + } + DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); @@ -1130,7 +1091,8 @@ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); (void) E1000_READ_REG(hw, E1000_ICR); - (void) e1000_check_alt_mac_addr_generic(hw); + /* Install any alternate MAC address into RAR0 */ + ret_val = e1000_check_alt_mac_addr_generic(hw); return (ret_val); } @@ -1151,7 +1113,7 @@ DEBUGFUNC("e1000_init_hw_82575"); /* 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 */ @@ -1162,7 +1124,7 @@ mac->ops.clear_vfta(hw); /* Setup the receive address */ - e1000_init_rx_addrs_82575(hw, rar_count); + e1000_init_rx_addrs_generic(hw, rar_count); /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) @@ -1193,7 +1155,7 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) { - u32 ctrl, led_ctrl; + u32 ctrl; s32 ret_val; bool link; @@ -1210,11 +1172,6 @@ break; case e1000_phy_igp_3: ret_val = e1000_copper_link_setup_igp(hw); - /* Setup activity LED */ - led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl); break; default: ret_val = -E1000_ERR_PHY; @@ -1294,13 +1251,13 @@ */ E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); - /* Force link up, set 1gb, set both sw defined pins */ + /* Force link up, set 1gb */ reg = E1000_READ_REG(hw, E1000_CTRL); - reg |= E1000_CTRL_SLU | - E1000_CTRL_SPD_1000 | - E1000_CTRL_FRCSPD | - E1000_CTRL_SWDPIN0 | - E1000_CTRL_SWDPIN1; + reg |= E1000_CTRL_SLU | E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD; + if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) { + /* set both sw defined pins */ + reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; + } E1000_WRITE_REG(hw, E1000_CTRL, reg); /* Power on phy for 82576 fiber adapters */ @@ -1376,7 +1333,6 @@ 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; @@ -1469,12 +1425,6 @@ e1000_sgmii_active_82575(struct e1000_hw *hw) { struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; - - DEBUGFUNC("e1000_sgmii_active_82575"); - - if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576) - return (false); - return (dev_spec->sgmii_active); } @@ -1540,9 +1490,19 @@ s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_mac_addr_82575"); - 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); } @@ -1708,3 +1668,55 @@ (void) E1000_READ_REG(hw, E1000_RNBC); (void) E1000_READ_REG(hw, E1000_MPC); } + +/* + * e1000_set_pcie_completion_timeout - set pci-e completion timeout + * @hw: pointer to the HW structure + * + * The defaults for 82575 and 82576 should be in the range of 50us to 50ms, + * however the hardware default for these parts is 500us to 1ms which is less + * than the 10ms recommended by the pci-e spec. To address this we need to + * increase the value to either 10ms to 200ms for capability version 1 config, + * or 16ms to 55ms for version 2. + */ +static s32 +e1000_set_pcie_completion_timeout(struct e1000_hw *hw) +{ + u32 gcr = E1000_READ_REG(hw, E1000_GCR); + s32 ret_val = E1000_SUCCESS; + u16 pcie_devctl2; + + /* only take action if timeout value is defaulted to 0 */ + if (gcr & E1000_GCR_CMPL_TMOUT_MASK) + goto out; + + /* + * if capababilities version is type 1 we can write the + * timeout of 10ms to 200ms through the GCR register + */ + if (!(gcr & E1000_GCR_CAP_VER2)) { + gcr |= E1000_GCR_CMPL_TMOUT_10ms; + goto out; + } + + /* + * for version 2 capabilities we need to write the config space + * directly in order to set the completion timeout value for + * 16ms to 55ms + */ + ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, + &pcie_devctl2); + if (ret_val) + goto out; + + pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms; + + ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, + &pcie_devctl2); +out: + /* disable completion timeout resend */ + gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND; + + E1000_WRITE_REG(hw, E1000_GCR, gcr); + return (ret_val); +}
--- a/usr/src/uts/common/io/igb/igb_82575.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_82575.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.57 v2008-10-7 */ +/* IntelVersion: 1.77 v2-9-8_2009-6-12 */ #ifndef _IGB_82575_H #define _IGB_82575_H @@ -129,6 +129,7 @@ #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 #define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 +#define E1000_SRRCTL_DROP_EN 0x80000000 #define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F #define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 @@ -138,6 +139,7 @@ #define E1000_MRQC_ENABLE_RSS_4Q 0x00000002 #define E1000_MRQC_ENABLE_VMDQ 0x00000003 +#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x80000000 #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 @@ -214,7 +216,7 @@ } wb; /* writeback */ }; -#define E1000_RXDADV_RSSTYPE_MASK 0x0000F000 +#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F #define E1000_RXDADV_RSSTYPE_SHIFT 12 #define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0 #define E1000_RXDADV_HDRBUFLEN_SHIFT 5 @@ -316,6 +318,7 @@ #define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ #define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ #define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */ /* IPSec Encrypt Enable for ESP */ #define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000 @@ -358,11 +361,10 @@ #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 */ +#define E1000_DCA_TXCTRL_CPUID_SHIFT_82576 24 /* Tx CPUID */ +#define E1000_DCA_RXCTRL_CPUID_SHIFT_82576 24 /* Rx CPUID */ /* Additional interrupt register bit definitions */ #define E1000_ICR_LSECPNS 0x00000020 /* PN threshold - server */ @@ -387,10 +389,14 @@ #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 */ +/* Per VF MAC spoof control */ +#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF +/* Per VF VLAN spoof control */ +#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 #define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */ -#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */ +#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 +#define E1000_DTXSWC_LLE_SHIFT 16 +#define E1000_DTXSWC_VMDQ_LOOPBACK_EN ((u32)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 @@ -402,84 +408,35 @@ #define E1000_VT_CTL_VM_REPL_EN (1 << 30) /* Per VM Offload register setup */ +#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */ #define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */ +#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */ #define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */ +#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */ +#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */ #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 */ +#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ -/* - * 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 */ +#define E1000_VLVF_ARRAY_SIZE 32 +#define E1000_VLVF_VLANID_MASK 0x00000FFF +#define E1000_VLVF_POOLSEL_SHIFT 12 +#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT) +#define E1000_VLVF_LVLAN 0x00100000 +#define E1000_VLVF_VLANID_ENABLE 0x80000000 -/* - * 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_VF_INIT_TIMEOUT 200 /* Number of retries to clear RSTI */ -#define E1000_PF_MSG_LSCDOWN (1 << E1000_VT_MSGINFO_SHIFT) -#define E1000_PF_MSG_LSCUP (2 << E1000_VT_MSGINFO_SHIFT) - -#define ALL_QUEUES 0xFFFF +#define E1000_IOVCTL 0x05BBC +#define E1000_IOVCTL_REUSE_VFQ 0x00000001 -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*); +#define E1000_RPLOLR_STRVLAN 0x40000000 +#define ALL_QUEUES 0xFFFF + +void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable); +void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable); #ifdef __cplusplus }
--- a/usr/src/uts/common/io/igb/igb_api.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_api.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.107 v2008-10-7 */ +/* IntelVersion: 1.122 v2-9-8_2009-6-12 */ #include "igb_api.h" @@ -138,6 +138,8 @@ case E1000_DEV_ID_82576_FIBER: case E1000_DEV_ID_82576_SERDES: case E1000_DEV_ID_82576_QUAD_COPPER: + case E1000_DEV_ID_82576_NS: + case E1000_DEV_ID_82576_SERDES_QUAD: mac->type = e1000_82576; break; default: @@ -278,26 +280,17 @@ * @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. + * Updates the 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. Currently no func pointer - * exists and all implementations are handled in the generic version of this - * function. */ 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) + u32 mc_addr_count) { 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, - rar_count); + mc_addr_list, mc_addr_count); } /* @@ -480,6 +473,22 @@ } /* + * e1000_id_led_init - store LED configurations in SW + * @hw: pointer to the HW structure + * + * Initializes the LED config in SW. This is a function pointer entry point + * called by drivers. + */ +s32 +e1000_id_led_init(struct e1000_hw *hw) +{ + if (hw->mac.ops.id_led_init) + return (hw->mac.ops.id_led_init(hw)); + + return (E1000_SUCCESS); +} + +/* * e1000_led_on - Turn on SW controllable LED * @hw: pointer to the HW structure *
--- a/usr/src/uts/common/io/igb/igb_api.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_api.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.50 v2008-10-7 */ +/* IntelVersion: 1.52 v2-9-8_2009-6-12 */ #ifndef _IGB_API_H #define _IGB_API_H @@ -62,14 +62,14 @@ void e1000_mta_set(struct e1000_hw *hw, u32 hash_value); u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr); 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); + u8 *mc_addr_list, u32 mc_addr_count); s32 e1000_setup_led(struct e1000_hw *hw); s32 e1000_cleanup_led(struct e1000_hw *hw); s32 e1000_check_reset_block(struct e1000_hw *hw); s32 e1000_blink_led(struct e1000_hw *hw); s32 e1000_led_on(struct e1000_hw *hw); s32 e1000_led_off(struct e1000_hw *hw); +s32 e1000_id_led_init(struct e1000_hw *hw); void e1000_reset_adaptive(struct e1000_hw *hw); void e1000_update_adaptive(struct e1000_hw *hw); s32 e1000_get_cable_length(struct e1000_hw *hw);
--- a/usr/src/uts/common/io/igb/igb_defines.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_defines.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.79 v2008-10-7 */ +/* IntelVersion: 1.111 v2-9-8_2009-6-12 */ #ifndef _IGB_DEFINES_H #define _IGB_DEFINES_H @@ -131,6 +131,8 @@ #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 */ +/* DMA Dynamic Clock Gating */ +#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 #define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 @@ -382,6 +384,7 @@ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ +#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */ #define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ #define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ #define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ @@ -458,6 +461,7 @@ #define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */ #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ /* Change in Dock/Undock state. Clear on write '0'. */ +#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */ #define E1000_STATUS_DOCK_CI 0x00000800 #define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */ #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ @@ -667,14 +671,19 @@ /* PBA constants */ #define E1000_PBA_6K 0x0006 /* 6KB */ #define E1000_PBA_8K 0x0008 /* 8KB */ +#define E1000_PBA_10K 0x000A /* 10KB */ #define E1000_PBA_12K 0x000C /* 12KB */ +#define E1000_PBA_14K 0x000E /* 14KB */ #define E1000_PBA_16K 0x0010 /* 16KB */ +#define E1000_PBA_18K 0x0012 #define E1000_PBA_20K 0x0014 #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 +#define E1000_PBA_26K 0x001A #define E1000_PBA_30K 0x001E #define E1000_PBA_32K 0x0020 #define E1000_PBA_34K 0x0022 +#define E1000_PBA_35K 0x0023 #define E1000_PBA_38K 0x0026 #define E1000_PBA_40K 0x0028 #define E1000_PBA_48K 0x0030 /* 48KB */ @@ -695,6 +704,9 @@ #define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ #define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ +/* Secondary driver semaphore bit */ +#define E1000_SWSM2_LOCK 0x00000002 + /* Interrupt Cause Read */ #define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ #define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ @@ -871,6 +883,8 @@ #define E1000_EICS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ #define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ +#define E1000_EITR_ITR_INT_MASK 0x0000FFFF + /* Transmit Descriptor Control */ #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ #define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ @@ -901,6 +915,10 @@ */ #define E1000_RAR_ENTRIES 15 #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ +#define E1000_RAL_MAC_ADDR_LEN 4 +#define E1000_RAH_MAC_ADDR_LEN 2 +#define E1000_RAH_POOL_MASK 0x03FC0000 +#define E1000_RAH_POOL_1 0x00040000 /* Error Codes */ #define E1000_SUCCESS 0 @@ -916,6 +934,7 @@ #define E1000_BLK_PHY_RESET 12 #define E1000_ERR_SWFW_SYNC 13 #define E1000_NOT_IMPLEMENTED 14 +#define E1000_ERR_MBX 15 /* Loop limit on how long we wait for auto-negotiation to complete */ #define FIBER_LINK_UP_LIMIT 50 @@ -965,6 +984,10 @@ #define E1000_GCR_TXD_NO_SNOOP 0x00000008 #define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 #define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 +#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 +#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define E1000_GCR_CAP_VER2 0x00040000 #define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ E1000_GCR_RXDSCW_NO_SNOOP | \ @@ -1080,6 +1103,8 @@ #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ +#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */ + /* NVM Control */ #define E1000_EECD_SK 0x00000001 /* NVM Clock */ #define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ @@ -1110,6 +1135,7 @@ #define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ #define E1000_EECD_SECVAL_SHIFT 22 +#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES) #define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */ #define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */ @@ -1213,22 +1239,14 @@ #define IGP_LED3_MODE 0x07000000 /* PCI/PCI-X/PCI-EX Config space */ -#define PCIX_COMMAND_REGISTER 0xE6 -#define PCIX_STATUS_REGISTER_LO 0xE8 -#define PCIX_STATUS_REGISTER_HI 0xEA #define PCI_HEADER_TYPE_REGISTER 0x0E #define PCIE_LINK_STATUS 0x12 +#define PCIE_DEVICE_CONTROL2 0x28 -#define PCIX_COMMAND_MMRBC_MASK 0x000C -#define PCIX_COMMAND_MMRBC_SHIFT 0x2 -#define PCIX_STATUS_HI_MMRBC_MASK 0x0060 -#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 -#define PCIX_STATUS_HI_MMRBC_4K 0x3 -#define PCIX_STATUS_HI_MMRBC_2K 0x2 -#define PCIX_STATUS_LO_FUNC_MASK 0x7 #define PCI_HEADER_TYPE_MULTIFUNC 0x80 #define PCIE_LINK_WIDTH_MASK 0x3F0 #define PCIE_LINK_WIDTH_SHIFT 4 +#define PCIE_DEVICE_CONTROL2_16ms 0x0005 #ifndef ETH_ADDR_LEN #define ETH_ADDR_LEN 6
--- a/usr/src/uts/common/io/igb/igb_hw.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_hw.h Sun Aug 16 19:52:03 2009 +0800 @@ -45,6 +45,8 @@ #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_82576_NS 0x150A +#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D #define E1000_DEV_ID_82575EB_COPPER 0x10A7 #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 #define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6 @@ -57,6 +59,8 @@ #define E1000_FUNC_0 0 #define E1000_FUNC_1 1 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 enum e1000_mac_type { e1000_undefined = 0, @@ -166,6 +170,13 @@ e1000_smart_speed_off }; +enum e1000_serdes_link_state { + e1000_serdes_link_down = 0, + e1000_serdes_link_autoneg_progress, + e1000_serdes_link_autoneg_complete, + e1000_serdes_link_forced_up +}; + /* Receive Descriptor */ struct e1000_rx_desc { __le64 buffer_addr; /* Address of the descriptor's data buffer */ @@ -436,6 +447,7 @@ struct e1000_mac_operations { /* Function pointers for the MAC. */ s32 (*init_params)(struct e1000_hw *); + s32 (*id_led_init)(struct e1000_hw *); s32 (*blink_led)(struct e1000_hw *); s32 (*check_for_link)(struct e1000_hw *); bool (*check_mng_mode)(struct e1000_hw *hw); @@ -443,10 +455,11 @@ void (*clear_hw_cntrs)(struct e1000_hw *); void (*clear_vfta)(struct e1000_hw *); s32 (*get_bus_info)(struct e1000_hw *); + void (*set_lan_id)(struct e1000_hw *); s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); 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 (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32); s32 (*reset_hw)(struct e1000_hw *); s32 (*init_hw)(struct e1000_hw *); void (*shutdown_serdes)(struct e1000_hw *); @@ -519,6 +532,10 @@ u16 ifs_ratio; u16 ifs_step_size; u16 mta_reg_count; + + /* Maximum size of the MTA register table in all supported adapters */ +#define MAX_MTA_REG 128 + u32 mta_shadow[MAX_MTA_REG]; u16 rar_entry_count; u8 forced_speed_duplex; @@ -530,6 +547,7 @@ bool autoneg_failed; bool get_link_status; bool in_ifs_mode; + enum e1000_serdes_link_state serdes_link_state; bool serdes_has_link; bool tx_pkt_filtering; }; @@ -604,10 +622,12 @@ struct e1000_dev_spec_82575 { bool sgmii_active; + bool global_device_reset; }; struct e1000_dev_spec_vf { u32 vf_number; + u32 v2p_mailbox; }; struct e1000_hw { @@ -641,8 +661,7 @@ /* These functions must be implemented by drivers */ s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); -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); +s32 e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); #ifdef __cplusplus }
--- a/usr/src/uts/common/io/igb/igb_mac.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_mac.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.92 v2008-10-7 */ +/* IntelVersion: 1.104 v2-9-8_2009-6-12 */ #include "igb_api.h" @@ -34,6 +34,7 @@ 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); +static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw); /* * e1000_init_mac_ops_generic - Initialize MAC function pointers @@ -53,6 +54,7 @@ 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.set_lan_id = e1000_set_lan_id_multi_port_pcie; 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; @@ -133,10 +135,10 @@ * @hw: pointer to the HW structure */ void -e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c) +e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a) { DEBUGFUNC("e1000_null_update_mc"); - UNREFERENCED_5PARAMETER(hw, h, a, b, c); + UNREFERENCED_3PARAMETER(hw, h, a); } /* @@ -173,67 +175,6 @@ } /* - * e1000_get_bus_info_pci_generic - Get PCI(x) bus information - * @hw: pointer to the HW structure - * - * Determines and stores the system bus information for a particular - * network interface. The following bus information is determined and stored: - * bus speed, bus width, type (PCI/PCIx), and PCI(-x) function. - */ -s32 -e1000_get_bus_info_pci_generic(struct e1000_hw *hw) -{ - struct e1000_bus_info *bus = &hw->bus; - u32 status = E1000_READ_REG(hw, E1000_STATUS); - s32 ret_val = E1000_SUCCESS; - u16 pci_header_type; - - DEBUGFUNC("e1000_get_bus_info_pci_generic"); - - /* PCI or PCI-X? */ - bus->type = (status & E1000_STATUS_PCIX_MODE) - ? 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; - } else { - switch (status & E1000_STATUS_PCIX_SPEED) { - case E1000_STATUS_PCIX_SPEED_66: - bus->speed = e1000_bus_speed_66; - break; - case E1000_STATUS_PCIX_SPEED_100: - bus->speed = e1000_bus_speed_100; - break; - case E1000_STATUS_PCIX_SPEED_133: - bus->speed = e1000_bus_speed_133; - break; - default: - bus->speed = e1000_bus_speed_reserved; - break; - } - } - - /* Bus width */ - bus->width = (status & E1000_STATUS_BUS64) - ? e1000_bus_width_64 - : e1000_bus_width_32; - - /* Which PCI(-X) function? */ - e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type); - if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) - bus->func = (status & E1000_STATUS_FUNC_MASK) - >> E1000_STATUS_FUNC_SHIFT; - else - bus->func = 0; - - return (ret_val); -} - -/* * e1000_get_bus_info_pcie_generic - Get PCIe bus information * @hw: pointer to the HW structure * @@ -244,10 +185,10 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) { + struct e1000_mac_info *mac = &hw->mac; struct e1000_bus_info *bus = &hw->bus; s32 ret_val; - u32 status; - u16 pcie_link_status, pci_header_type; + u16 pcie_link_status; DEBUGFUNC("e1000_get_bus_info_pcie_generic"); @@ -262,19 +203,48 @@ 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); - if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) { - status = E1000_READ_REG(hw, E1000_STATUS); - bus->func = (status & E1000_STATUS_FUNC_MASK) - >> E1000_STATUS_FUNC_SHIFT; - } else { - bus->func = 0; - } + mac->ops.set_lan_id(hw); return (E1000_SUCCESS); } /* + * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices + * + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers + * and swaps the port value if requested. + */ +static void +e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + u32 reg; + + /* + * The status register reports the correct function number + * for the device regardless of function swap state. + */ + reg = E1000_READ_REG(hw, E1000_STATUS); + bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; +} + +/* + * e1000_set_lan_id_single_port - Set LAN id for a single port device + * @hw: pointer to the HW structure + * + * Sets the LAN function id to zero for a single port device. + */ +void +e1000_set_lan_id_single_port(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + + bus->func = 0; +} + +/* * e1000_clear_vfta_generic - Clear VLAN filter table * @hw: pointer to the HW structure * @@ -325,6 +295,7 @@ e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) { u32 i; + u8 mac_addr[ETH_ADDR_LEN] = {0}; DEBUGFUNC("e1000_init_rx_addrs_generic"); @@ -335,12 +306,8 @@ /* 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++) { - E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); - E1000_WRITE_FLUSH(hw); - E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); - E1000_WRITE_FLUSH(hw); - } + for (i = 1; i < rar_count; i++) + hw->mac.ops.rar_set(hw, mac_addr, i); } /* @@ -350,9 +317,10 @@ * Checks the nvm for an alternate MAC address. An alternate MAC address * can be setup by pre-boot software and must be treated like a permanent * address and must override the actual permanent MAC address. If an - * alternate MAC address is found it is saved in the hw struct and - * programmed into RAR0 and the function returns success, otherwise the - * function returns an error. + * alternate MAC address is found it is programmed into RAR0, replacing + * the permanent address that was installed into RAR0 by the Si on reset. + * This function will return SUCCESS unless it encounters an error while + * reading the EEPROM. */ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) @@ -372,13 +340,12 @@ } if (nvm_alt_mac_addr_offset == 0xFFFF) { - ret_val = -(E1000_NOT_IMPLEMENTED); + /* There is no Alternate MAC Address */ goto out; } if (hw->bus.func == E1000_FUNC_1) - nvm_alt_mac_addr_offset += ETH_ADDR_LEN / sizeof (u16); - + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; for (i = 0; i < ETH_ADDR_LEN; i += 2) { offset = nvm_alt_mac_addr_offset + (i >> 1); ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); @@ -393,14 +360,16 @@ /* if multicast bit is set, the alternate address will not be used */ if (alt_mac_addr[0] & 0x01) { - ret_val = -(E1000_NOT_IMPLEMENTED); + DEBUGOUT("Ignoring Alternate Mac Address with MC bit set\n"); goto out; } - for (i = 0; i < ETH_ADDR_LEN; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; - - hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0); + /* + * We have a valid alternate MAC address, and we want to treat it the + * same as the normal permanent MAC address stored by the HW into the + * RAR. Do this by mapping this address into RAR0. + */ + hw->mac.ops.rar_set(hw, alt_mac_addr, 0); out: return (ret_val); @@ -436,8 +405,15 @@ if (rar_low || rar_high) rar_high |= E1000_RAH_AV; + /* + * Some bridges will combine consecutive 32-bit writes into + * a single burst write, which will malfunction on some parts. + * The flushes avoid this. + */ E1000_WRITE_REG(hw, E1000_RAL(index), rar_low); + E1000_WRITE_FLUSH(hw); E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); + E1000_WRITE_FLUSH(hw); } /* @@ -482,56 +458,37 @@ * @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. + * Updates the 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. */ 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) + u8 *mc_addr_list, u32 mc_addr_count) { - u32 hash_value; - u32 i; + u32 hash_value, hash_bit, hash_reg; + int i; DEBUGFUNC("e1000_update_mc_addr_list_generic"); - /* - * 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) { - hw->mac.ops.rar_set(hw, mc_addr_list, i); - mc_addr_count--; - mc_addr_list += ETH_ADDR_LEN; - } else { - E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0); - E1000_WRITE_FLUSH(hw); - E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0); - E1000_WRITE_FLUSH(hw); - } + /* clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof (hw->mac.mta_shadow)); + + /* update mta_shadow from mc_addr_list */ + for (i = 0; (u32) i < mc_addr_count; i++) { + hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list); + + hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); + hash_bit = hash_value & 0x1F; + + hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); + mc_addr_list += (ETH_ADDR_LEN); } - /* 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_generic(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; - } + /* replace the entire MTA table */ + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); + E1000_WRITE_FLUSH(hw); } /* @@ -609,44 +566,6 @@ } /* - * e1000_pcix_mmrbc_workaround_generic - Fix incorrect MMRBC value - * @hw: pointer to the HW structure - * - * 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 register with the current PCIx status - * register. - */ -void -e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw) -{ - u16 cmd_mmrbc; - u16 pcix_cmd; - u16 pcix_stat_hi_word; - u16 stat_mmrbc; - - DEBUGFUNC("e1000_pcix_mmrbc_workaround_generic"); - - /* Workaround for PCI-X issue when BIOS sets MMRBC incorrectly */ - if (hw->bus.type != e1000_bus_type_pcix) - return; - - e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd); - e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); - cmd_mmrbc = (pcix_cmd & PCIX_COMMAND_MMRBC_MASK) >> - PCIX_COMMAND_MMRBC_SHIFT; - stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> - PCIX_STATUS_HI_MMRBC_SHIFT; - if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) - stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; - if (cmd_mmrbc > stat_mmrbc) { - pcix_cmd &= ~PCIX_COMMAND_MMRBC_MASK; - pcix_cmd |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; - e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd); - } -} - -/* * e1000_clear_hw_cntrs_base_generic - Clear base hardware counters * @hw: pointer to the HW structure *
--- a/usr/src/uts/common/io/igb/igb_mac.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_mac.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.29 v2008-10-7 */ +/* IntelVersion: 1.32 v2-9-8_2009-6-12 */ #ifndef _IGB_MAC_H #define _IGB_MAC_H @@ -44,7 +44,7 @@ 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_update_mc(struct e1000_hw *hw, u8 *h, u32 a); 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); @@ -57,8 +57,8 @@ s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw); s32 e1000_force_mac_fc_generic(struct e1000_hw *hw); s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw); -s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw); s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw); +void e1000_set_lan_id_single_port(struct e1000_hw *hw); s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw); s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, u16 *duplex); @@ -68,8 +68,7 @@ s32 e1000_led_on_generic(struct e1000_hw *hw); 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); + u8 *mc_addr_list, u32 mc_addr_count); 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);
--- a/usr/src/uts/common/io/igb/igb_main.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_main.c Sun Aug 16 19:52:03 2009 +0800 @@ -29,7 +29,7 @@ #include "igb_sw.h" static char ident[] = "Intel 1Gb Ethernet"; -static char igb_version[] = "igb 1.1.7"; +static char igb_version[] = "igb 1.1.8"; /* * Local function protoypes @@ -2584,8 +2584,7 @@ /* * Update the multicase addresses to the MTA registers */ - e1000_update_mc_addr_list(hw, mc_addr_list, mc_addr_count, - igb->unicst_total, hw->mac.rar_entry_count); + e1000_update_mc_addr_list(hw, mc_addr_list, mc_addr_count); } /* @@ -2680,7 +2679,7 @@ igb->rx_ring_size = igb_get_prop(igb, PROP_RX_RING_SIZE, MIN_RX_RING_SIZE, MAX_RX_RING_SIZE, DEFAULT_RX_RING_SIZE); - igb->mr_enable = igb_get_prop(igb, PROP_MR_ENABLE, 0, 1, 1); + igb->mr_enable = igb_get_prop(igb, PROP_MR_ENABLE, 0, 1, 0); igb->num_rx_groups = igb_get_prop(igb, PROP_RX_GROUP_NUM, MIN_RX_GROUP_NUM, MAX_RX_GROUP_NUM, DEFAULT_RX_GROUP_NUM); /*
--- a/usr/src/uts/common/io/igb/igb_manage.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_manage.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.27 v2008-10-7 */ +/* IntelVersion: 1.27 v2-9-8_2009-6-12 */ #include "igb_api.h"
--- a/usr/src/uts/common/io/igb/igb_manage.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_manage.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.18 v2008-10-7 */ +/* IntelVersion: 1.18 v2-9-8_2009-6-12 */ #ifndef _IGB_MANAGE_H #define _IGB_MANAGE_H
--- a/usr/src/uts/common/io/igb/igb_nvm.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_nvm.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.46 v2008-10-7 */ +/* IntelVersion: 1.49 v2-9-8_2009-6-12 */ #include "igb_api.h" @@ -771,31 +771,23 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) { - s32 ret_val = E1000_SUCCESS; - u16 offset, nvm_data, i; - - DEBUGFUNC("e1000_read_mac_addr"); + u32 rar_high; + u32 rar_low; + u16 i; - 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); - } + rar_high = E1000_READ_REG(hw, E1000_RAH(0)); + rar_low = E1000_READ_REG(hw, E1000_RAL(0)); - /* 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 < E1000_RAL_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); + + for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); for (i = 0; i < ETH_ADDR_LEN; i++) hw->mac.addr[i] = hw->mac.perm_addr[i]; -out: - return (ret_val); + return (E1000_SUCCESS); } /*
--- a/usr/src/uts/common/io/igb/igb_nvm.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_nvm.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.18 v2008-10-7 */ +/* IntelVersion: 1.18 v2-9-8_2009-6-12 */ #ifndef _IGB_NVM_H #define _IGB_NVM_H
--- a/usr/src/uts/common/io/igb/igb_osdep.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_osdep.c Sun Aug 16 19:52:03 2009 +0800 @@ -31,22 +31,6 @@ void -e1000_pci_set_mwi(struct e1000_hw *hw) -{ - uint16_t val = hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE; - - e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); -} - -void -e1000_pci_clear_mwi(struct e1000_hw *hw) -{ - uint16_t val = hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE; - - e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &val); -} - -void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) { pci_config_put16(OS_DEP(hw)->cfg_handle, reg, *value); @@ -61,25 +45,50 @@ /* * Return the 16-bit value from pci-e config space at offset reg into the pci-e - * capability block. + * capability block. Note that this refers to the pci-e capability block in + * standard pci config space, not the block in pci-e extended config space. */ int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) { - uint32_t pcie_cap = PCI_EX_CONF_CAP; /* default */ + uint8_t pcie_id = PCI_CAP_ID_PCI_E; + uint16_t pcie_cap; + int32_t status; - switch (hw->mac.type) { - case e1000_82575: - pcie_cap = 0xa0; - break; - case e1000_82576: - pcie_cap = 0xa0; - break; + /* locate the pci-e capability block */ + status = pci_lcap_locate((OS_DEP(hw))->cfg_handle, pcie_id, &pcie_cap); + if (status == DDI_SUCCESS) { + + /* read at given offset into block */ + *value = pci_config_get16(OS_DEP(hw)->cfg_handle, + (pcie_cap + reg)); } - *value = pci_config_get16(OS_DEP(hw)->cfg_handle, (pcie_cap + reg)); + return (status); +} - return (0); +/* + * Write the given 16-bit value to pci-e config space at offset reg into the + * pci-e capability block. Note that this refers to the pci-e capability block + * in standard pci config space, not the block in pci-e extended config space. + */ +int32_t +e1000_write_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + uint8_t pcie_id = PCI_CAP_ID_PCI_E; + uint16_t pcie_cap; + int32_t status; + + /* locate the pci-e capability block */ + status = pci_lcap_locate(OS_DEP(hw)->cfg_handle, pcie_id, &pcie_cap); + if (status == DDI_SUCCESS) { + + /* write at given offset into block */ + pci_config_put16(OS_DEP(hw)->cfg_handle, + (off_t)(pcie_cap + reg), *value); + } + + return (status); } /*
--- a/usr/src/uts/common/io/igb/igb_osdep.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_osdep.h Sun Aug 16 19:52:03 2009 +0800 @@ -48,6 +48,7 @@ #include <sys/dditypes.h> #include <sys/sunddi.h> #include <sys/pci.h> +#include <sys/pci_cap.h> #include <sys/atomic.h> #include <sys/note.h> #include "igb_debug.h"
--- a/usr/src/uts/common/io/igb/igb_phy.c Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_phy.c Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.112 v2008-10-7 */ +/* IntelVersion: 1.140 v2-9-8_2009-6-12 */ #include "igb_api.h" @@ -1283,6 +1283,76 @@ } /* + * e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex + * @hw: pointer to the HW structure + * + * Forces the speed and duplex settings of the PHY. + * This is a function pointer entry point only called by + * PHY setup routines. + */ +s32 +e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 data; + bool link; + + DEBUGFUNC("e1000_phy_force_speed_duplex_ife"); + + if (phy->type != e1000_phy_ife) { + ret_val = e1000_phy_force_speed_duplex_igp(hw); + goto out; + } + + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data); + if (ret_val) + goto out; + + e1000_phy_force_speed_duplex_setup(hw, &data); + + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data); + if (ret_val) + goto out; + + /* Disable MDI-X support for 10/100 */ + ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); + if (ret_val) + goto out; + + data &= ~IFE_PMC_AUTO_MDIX; + data &= ~IFE_PMC_FORCE_MDIX; + + ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data); + if (ret_val) + goto out; + + DEBUGOUT1("IFE PMC: %X\n", data); + + usec_delay(1); + + if (phy->autoneg_wait_to_complete) { + DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n"); + + ret_val = e1000_phy_has_link_generic(hw, + PHY_FORCE_LIMIT, 100000, &link); + if (ret_val) + goto out; + + if (!link) + DEBUGOUT("Link taking longer than expected.\n"); + + /* Try once more */ + ret_val = e1000_phy_has_link_generic(hw, + PHY_FORCE_LIMIT, 100000, &link); + if (ret_val) + goto out; + } + +out: + return (ret_val); +} +/* * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex * @hw: pointer to the HW structure * @phy_ctrl: pointer to current value of PHY_CONTROL @@ -1566,6 +1636,41 @@ } /* + * e1000_check_polarity_ife - Check cable polarity for IFE PHY + * @hw: pointer to the HW structure + * + * Polarity is determined on the polarity reversal feature being enabled. + */ +s32 +e1000_check_polarity_ife(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_data, offset, mask; + + DEBUGFUNC("e1000_check_polarity_ife"); + + /* + * Polarity is determined based on the reversal feature being enabled. + */ + if (phy->polarity_correction) { + offset = IFE_PHY_EXTENDED_STATUS_CONTROL; + mask = IFE_PESC_POLARITY_REVERSED; + } else { + offset = IFE_PHY_SPECIAL_CONTROL; + mask = IFE_PSC_FORCE_POLARITY; + } + + ret_val = phy->ops.read_reg(hw, offset, &phy_data); + + if (!ret_val) + phy->cable_polarity = (phy_data & mask) + ? e1000_rev_polarity_reversed + : e1000_rev_polarity_normal; + + return (ret_val); +} +/* * e1000_wait_autoneg_generic - Wait for auto-neg completion * @hw: pointer to the HW structure * @@ -1631,9 +1736,16 @@ * it across the board. */ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); - if (ret_val) - break; - ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); + if (ret_val) { + /* + * If the first read fails, another entity may have + * ownership of the resources, wait and try again to + * see if they have relinquished the resources yet. + */ + usec_delay(usec_interval); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, + &phy_status); + } if (ret_val) break; if (phy_status & MII_SR_LINK_STATUS) @@ -1680,14 +1792,15 @@ index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> M88E1000_PSSR_CABLE_LENGTH_SHIFT; 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]; + ret_val = E1000_ERR_PHY; + goto out; + } - phy->cable_length = (phy->min_cable_length + - phy->max_cable_length) / 2; - } else { - ret_val = E1000_ERR_PHY; - } + 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; out: return (ret_val); @@ -2140,6 +2253,48 @@ } /* + * 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; + enum e1000_phy_type phy_type = e1000_phy_unknown; + + hw->phy.id = phy_type; + + for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) { + hw->phy.addr = phy_addr; + i = 0; + + do { + 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; + goto out; + } + msec_delay(1); + i++; + } while (i < 10); + } + +out: + return (ret_val); +} +/* * e1000_power_up_phy_copper - Restore copper link in case of PHY power down * @hw: pointer to the HW structure *
--- a/usr/src/uts/common/io/igb/igb_phy.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_phy.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.55 v2008-10-7 */ +/* IntelVersion: 1.69 v2-9-8_2009-6-12 */ #ifndef _IGB_PHY_H #define _IGB_PHY_H @@ -43,12 +43,14 @@ 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_polarity_ife(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_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); s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw); +s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw); s32 e1000_get_cable_length_m88(struct e1000_hw *hw); s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw); s32 e1000_get_cfg_done_generic(struct e1000_hw *hw); @@ -73,6 +75,7 @@ u32 usec_interval, bool *success); s32 e1000_phy_init_script_igp3(struct e1000_hw *hw); enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id); +s32 e1000_determine_phy_address(struct e1000_hw *hw); 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); @@ -112,7 +115,7 @@ #define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 #define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 -#define IGP01E1000_PSSR_MDIX 0x0008 +#define IGP01E1000_PSSR_MDIX 0x0800 #define IGP01E1000_PSSR_SPEED_MASK 0xC000 #define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 @@ -135,6 +138,8 @@ #define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16 #define E1000_KMRNCTRLSTA_REN 0x00200000 #define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ +#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */ +#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */ #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
--- a/usr/src/uts/common/io/igb/igb_regs.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_regs.h Sun Aug 16 19:52:03 2009 +0800 @@ -26,7 +26,7 @@ * Use is subject to license terms of the CDDL. */ -/* IntelVersion: 1.61 v2008-10-7 */ +/* IntelVersion: 1.70 v2-9-8_2009-6-12 */ #ifndef _IGB_REGS_H #define _IGB_REGS_H @@ -426,6 +426,7 @@ #define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ #define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */ #define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */ #define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ #define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ #define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ @@ -434,6 +435,8 @@ #define E1000_FACTPS 0x05B30 #define E1000_SWSM 0x05B50 /* SW Semaphore */ #define E1000_FWSM 0x05B54 /* FW Semaphore */ +/* Driver-only SW semaphore (not used by BOOT agents) */ +#define E1000_SWSM2 0x05B58 #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 */ @@ -472,7 +475,6 @@ #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 */ @@ -483,12 +485,15 @@ #define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) #define E1000_VFVMBMEM(_n) (0x00800 + (_n)) #define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) +/* VLAN Virtual Machine Filter - RW */ +#define E1000_VLVF(_n) (0x05D00 + (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_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */ #define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */ #define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
--- a/usr/src/uts/common/io/igb/igb_sw.h Sun Aug 16 16:01:00 2009 +0800 +++ b/usr/src/uts/common/io/igb/igb_sw.h Sun Aug 16 19:52:03 2009 +0800 @@ -830,6 +830,10 @@ /* * Function prototypes in e1000_osdep.c */ +void e1000_write_pci_cfg(struct e1000_hw *, uint32_t, uint16_t *); +void e1000_read_pci_cfg(struct e1000_hw *, uint32_t, uint16_t *); +int32_t e1000_read_pcie_cap_reg(struct e1000_hw *, uint32_t, uint16_t *); +int32_t e1000_write_pcie_cap_reg(struct e1000_hw *, uint32_t, uint16_t *); 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);