From owner-svn-src-all@FreeBSD.ORG Wed Nov 26 23:57:23 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BA3AA1065673; Wed, 26 Nov 2008 23:57:23 +0000 (UTC) (envelope-from jfv@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 99F2B8FC1E; Wed, 26 Nov 2008 23:57:23 +0000 (UTC) (envelope-from jfv@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mAQNvN88070051; Wed, 26 Nov 2008 23:57:23 GMT (envelope-from jfv@svn.freebsd.org) Received: (from jfv@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mAQNvNeZ070047; Wed, 26 Nov 2008 23:57:23 GMT (envelope-from jfv@svn.freebsd.org) Message-Id: <200811262357.mAQNvNeZ070047@svn.freebsd.org> From: Jack F Vogel Date: Wed, 26 Nov 2008 23:57:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r185353 - head/sys/dev/e1000 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Nov 2008 23:57:23 -0000 Author: jfv Date: Wed Nov 26 23:57:23 2008 New Revision: 185353 URL: http://svn.freebsd.org/changeset/base/185353 Log: This delta is primarily a fix for es2lan devices that will sometimes fail to initialize problem due to a lock contention with management hardware. However, in order to deliver that fix it was necessary to take a shared code update as a whole, and this required scattered changes in the core code to be compatible. The em driver now has VLAN HW support added as the igb driver had previously. MFC after: ASAP - in time for 7.1 RELEASE Modified: head/sys/dev/e1000/e1000_80003es2lan.c head/sys/dev/e1000/e1000_82540.c head/sys/dev/e1000/e1000_82541.c head/sys/dev/e1000/e1000_82542.c head/sys/dev/e1000/e1000_82543.c head/sys/dev/e1000/e1000_82571.c head/sys/dev/e1000/e1000_82575.c head/sys/dev/e1000/e1000_82575.h head/sys/dev/e1000/e1000_api.c head/sys/dev/e1000/e1000_api.h head/sys/dev/e1000/e1000_defines.h head/sys/dev/e1000/e1000_hw.h head/sys/dev/e1000/e1000_ich8lan.c head/sys/dev/e1000/e1000_ich8lan.h head/sys/dev/e1000/e1000_mac.c head/sys/dev/e1000/e1000_mac.h head/sys/dev/e1000/e1000_manage.c head/sys/dev/e1000/e1000_nvm.c head/sys/dev/e1000/e1000_osdep.c head/sys/dev/e1000/e1000_osdep.h head/sys/dev/e1000/e1000_phy.c head/sys/dev/e1000/e1000_phy.h head/sys/dev/e1000/e1000_regs.h head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_em.h head/sys/dev/e1000/if_igb.c Modified: head/sys/dev/e1000/e1000_80003es2lan.c ============================================================================== --- head/sys/dev/e1000/e1000_80003es2lan.c Wed Nov 26 23:41:18 2008 (r185352) +++ head/sys/dev/e1000/e1000_80003es2lan.c Wed Nov 26 23:57:23 2008 (r185353) @@ -32,7 +32,9 @@ ******************************************************************************/ /*$FreeBSD$*/ -/* e1000_80003es2lan +/* + * 80003ES2LAN Gigabit Ethernet Controller (Copper) + * 80003ES2LAN Gigabit Ethernet Controller (Serdes) */ #include "e1000_api.h" @@ -41,7 +43,9 @@ static s32 e1000_init_phy_params_80003e 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, @@ -64,6 +68,11 @@ static void e1000_clear_hw_cntrs_80003es static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); +static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); +static s32 e1000_read_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); static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); @@ -84,8 +93,6 @@ static const u16 e1000_gg82563_cable_len /** * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) { @@ -122,6 +129,8 @@ static s32 e1000_init_phy_params_80003es phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; + phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; + /* This can only be done after all function pointers are setup. */ ret_val = e1000_get_phy_id(hw); @@ -138,8 +147,6 @@ out: /** * e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) { @@ -197,8 +204,6 @@ static s32 e1000_init_nvm_params_80003es /** * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { @@ -280,8 +285,6 @@ static s32 e1000_init_mac_params_80003es /* turn on/off LED */ mac->ops.led_on = e1000_led_on_generic; mac->ops.led_off = e1000_led_off_generic; - /* remove device */ - mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; /* link info */ @@ -295,8 +298,7 @@ out: * e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs. * @hw: pointer to the HW structure * - * The only function explicitly called by the api module to initialize - * all function pointers and parameters. + * Called to initialize all function pointers and parameters. **/ void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) { @@ -305,14 +307,14 @@ void e1000_init_function_pointers_80003e 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); } /** * e1000_acquire_phy_80003es2lan - Acquire rights to access PHY * @hw: pointer to the HW structure * - * A wrapper to acquire access rights to the correct PHY. This is a - * function pointer entry point called by the api module. + * A wrapper to acquire access rights to the correct PHY. **/ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) { @@ -321,8 +323,6 @@ static s32 e1000_acquire_phy_80003es2lan DEBUGFUNC("e1000_acquire_phy_80003es2lan"); mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; - mask |= E1000_SWFW_CSR_SM; - return e1000_acquire_swfw_sync_80003es2lan(hw, mask); } @@ -330,8 +330,7 @@ static s32 e1000_acquire_phy_80003es2lan * e1000_release_phy_80003es2lan - Release rights to access PHY * @hw: pointer to the HW structure * - * A wrapper to release access rights to the correct PHY. This is a - * function pointer entry point called by the api module. + * A wrapper to release access rights to the correct PHY. **/ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) { @@ -340,7 +339,41 @@ static void e1000_release_phy_80003es2la DEBUGFUNC("e1000_release_phy_80003es2lan"); mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; - mask |= E1000_SWFW_CSR_SM; + e1000_release_swfw_sync_80003es2lan(hw, mask); +} + + +/** + * e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register + * @hw: pointer to the HW structure + * + * Acquire the semaphore to access the Kumeran interface. + * + **/ +static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw) +{ + u16 mask; + + DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan"); + + mask = E1000_SWFW_CSR_SM; + + return e1000_acquire_swfw_sync_80003es2lan(hw, mask); +} + +/** + * e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register + * @hw: pointer to the HW structure + * + * Release the semaphore used to access the Kumeran interface + **/ +static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw) +{ + u16 mask; + + DEBUGFUNC("e1000_release_mac_csr_80003es2lan"); + + mask = E1000_SWFW_CSR_SM; e1000_release_swfw_sync_80003es2lan(hw, mask); } @@ -349,8 +382,7 @@ static void e1000_release_phy_80003es2la * e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM * @hw: pointer to the HW structure * - * Acquire the semaphore to access the EEPROM. This is a function - * pointer entry point called by the api module. + * Acquire the semaphore to access the EEPROM. **/ static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) { @@ -375,8 +407,7 @@ out: * e1000_release_nvm_80003es2lan - Relinquish rights to access NVM * @hw: pointer to the HW structure * - * Release the semaphore used to access the EEPROM. This is a - * function pointer entry point called by the api module. + * Release the semaphore used to access the EEPROM. **/ static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) { @@ -400,7 +431,7 @@ static s32 e1000_acquire_swfw_sync_80003 u32 swmask = mask; u32 fwmask = mask << 16; s32 ret_val = E1000_SUCCESS; - s32 i = 0, timeout = 200; + s32 i = 0, timeout = 50; DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); @@ -452,8 +483,8 @@ static void e1000_release_swfw_sync_8000 DEBUGFUNC("e1000_release_swfw_sync_80003es2lan"); - while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS); - /* Empty */ + while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) + ; /* Empty */ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); swfw_sync &= ~mask; @@ -468,8 +499,7 @@ static void e1000_release_swfw_sync_8000 * @offset: offset of the register to read * @data: pointer to the data returned from the operation * - * Read the GG82563 PHY register. This is a function pointer entry - * point called by the api module. + * Read the GG82563 PHY register. **/ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data) @@ -520,9 +550,8 @@ static s32 e1000_read_phy_reg_gg82563_80 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); e1000_release_phy_80003es2lan(hw); @@ -537,8 +566,7 @@ out: * @offset: offset of the register to read * @data: value to write to the register * - * Write to the GG82563 PHY register. This is a function pointer entry - * point called by the api module. + * Write to the GG82563 PHY register. **/ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data) @@ -590,8 +618,7 @@ static s32 e1000_write_phy_reg_gg82563_8 usec_delay(200); - ret_val = e1000_write_phy_reg_mdic(hw, - MAX_PHY_REG_ADDRESS & offset, + ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); usec_delay(200); @@ -608,8 +635,7 @@ out: * @words: number of words to write * @data: buffer of data to write to the NVM * - * Write "words" of data to the ESB2 NVM. This is a function - * pointer entry point called by the api module. + * Write "words" of data to the ESB2 NVM. **/ static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) @@ -775,10 +801,17 @@ static s32 e1000_get_cable_length_80003e goto out; index = phy_data & GG82563_DSPD_CABLE_LENGTH; - 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; + 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; + } out: return ret_val; @@ -791,7 +824,6 @@ out: * @duplex: pointer to duplex buffer * * Retrieve the current speed and duplex configuration. - * This is a function pointer entry point called by the api module. **/ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) @@ -804,20 +836,13 @@ static s32 e1000_get_link_up_info_80003e ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); - if (ret_val) - goto out; - if (*speed == SPEED_1000) - ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); - else - ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, - *duplex); + hw->phy.ops.cfg_on_link_up(hw); } else { ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, speed, duplex); } -out: return ret_val; } @@ -826,7 +851,6 @@ out: * @hw: pointer to the HW structure * * Perform a global reset to the ESB2 controller. - * This is a function pointer entry point called by the api module. **/ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { @@ -840,9 +864,8 @@ static s32 e1000_reset_hw_80003es2lan(st * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); - if (ret_val) { + if (ret_val) DEBUGOUT("PCI-E Master disable polling has failed.\n"); - } DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); @@ -855,8 +878,10 @@ static s32 e1000_reset_hw_80003es2lan(st ctrl = E1000_READ_REG(hw, E1000_CTRL); + ret_val = e1000_acquire_phy_80003es2lan(hw); DEBUGOUT("Issuing a global reset to MAC\n"); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); + e1000_release_phy_80003es2lan(hw); ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) @@ -878,7 +903,6 @@ out: * @hw: pointer to the HW structure * * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) { @@ -969,9 +993,6 @@ static void e1000_initialize_hw_bits_800 DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan"); - if (hw->mac.disable_hw_init_bits) - goto out; - /* Transmit Descriptor Control 0 */ reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg |= (1 << 22); @@ -997,7 +1018,6 @@ static void e1000_initialize_hw_bits_800 reg |= (1 << 28); E1000_WRITE_REG(hw, E1000_TARC(1), reg); -out: return; } @@ -1012,8 +1032,7 @@ static s32 e1000_copper_link_setup_gg825 struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u32 ctrl_ext; - u32 i = 0; - u16 data, data2; + u16 data; DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); @@ -1084,20 +1103,20 @@ static s32 e1000_copper_link_setup_gg825 } /* Bypass Rx and Tx FIFO's */ - ret_val = e1000_write_kmrn_reg_generic(hw, + 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); if (ret_val) goto out; - ret_val = e1000_read_kmrn_reg_generic(hw, + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, &data); if (ret_val) goto out; data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; - ret_val = e1000_write_kmrn_reg_generic(hw, + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, data); if (ret_val) @@ -1129,30 +1148,20 @@ static s32 e1000_copper_link_setup_gg825 /* 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, - data); + GG82563_PHY_PWR_MGMT_CTRL, + data); if (ret_val) goto out; - - do { - 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, - &data2); + ret_val = hw->phy.ops.read_reg(hw, + GG82563_PHY_KMRN_MODE_CTRL, + &data); if (ret_val) goto out; - i++; - } while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY)); data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ret_val = hw->phy.ops.write_reg(hw, - GG82563_PHY_KMRN_MODE_CTRL, - data); + GG82563_PHY_KMRN_MODE_CTRL, + data); if (ret_val) goto out; @@ -1185,7 +1194,7 @@ out: static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) { u32 ctrl; - s32 ret_val; + s32 ret_val; u16 reg_data; DEBUGFUNC("e1000_setup_copper_link_80003es2lan"); @@ -1200,26 +1209,26 @@ static s32 e1000_setup_copper_link_80003 * iteration and increase the max iterations when * polling the phy; this fixes erroneous timeouts at 10Mbps. */ - ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 4), - 0xFFFF); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4), + 0xFFFF); if (ret_val) goto out; - ret_val = e1000_read_kmrn_reg_generic(hw, GG82563_REG(0x34, 9), - ®_data); + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), + ®_data); if (ret_val) goto out; reg_data |= 0x3F; - ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 9), - reg_data); + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), + reg_data); if (ret_val) goto out; - ret_val = e1000_read_kmrn_reg_generic(hw, + ret_val = e1000_read_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, ®_data); if (ret_val) goto out; reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; - ret_val = e1000_write_kmrn_reg_generic(hw, + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, reg_data); if (ret_val) @@ -1236,6 +1245,40 @@ out: } /** + * e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up + * @hw: pointer to the HW structure + * @duplex: current duplex setting + * + * Configure the KMRN interface by applying last minute quirks for + * 10/100 operation. + **/ +static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 speed; + u16 duplex; + + 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); + if (ret_val) + goto out; + + if (speed == SPEED_1000) + ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); + else + ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex); + } + +out: + return ret_val; +} + +/** * e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation * @hw: pointer to the HW structure * @duplex: current duplex setting @@ -1253,7 +1296,7 @@ static s32 e1000_cfg_kmrn_10_100_80003es DEBUGFUNC("e1000_configure_kmrn_for_10_100"); reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; - ret_val = e1000_write_kmrn_reg_generic(hw, + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, reg_data); if (ret_val) @@ -1268,12 +1311,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data); + ®_data); if (ret_val) goto out; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data2); + ®_data2); if (ret_val) goto out; i++; @@ -1307,7 +1350,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2l DEBUGFUNC("e1000_configure_kmrn_for_1000"); reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; - ret_val = e1000_write_kmrn_reg_generic(hw, + ret_val = e1000_write_kmrn_reg_80003es2lan(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, reg_data); if (ret_val) @@ -1322,12 +1365,12 @@ static s32 e1000_cfg_kmrn_1000_80003es2l do { ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data); + ®_data); if (ret_val) goto out; ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, - ®_data2); + ®_data2); if (ret_val) goto out; i++; @@ -1341,6 +1384,75 @@ out: } /** + * e1000_read_kmrn_reg_80003es2lan - Read kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to be read + * @data: pointer to the read data + * + * Acquire semaphore, then read the PHY register at offset + * 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) +{ + u32 kmrnctrlsta; + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan"); + + ret_val = e1000_acquire_mac_csr_80003es2lan(hw); + if (ret_val) + goto out; + + kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & + E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; + E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + + usec_delay(2); + + kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); + *data = (u16)kmrnctrlsta; + + e1000_release_mac_csr_80003es2lan(hw); + +out: + return ret_val; +} + +/** + * e1000_write_kmrn_reg_80003es2lan - Write kumeran register + * @hw: pointer to the HW structure + * @offset: register offset to write to + * @data: data to write at register offset + * + * Acquire semaphore, then write the data to PHY register + * 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) +{ + u32 kmrnctrlsta; + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan"); + + ret_val = e1000_acquire_mac_csr_80003es2lan(hw); + if (ret_val) + goto out; + + kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & + E1000_KMRNCTRLSTA_OFFSET) | data; + E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + + usec_delay(2); + + e1000_release_mac_csr_80003es2lan(hw); + +out: + return ret_val; +} + +/** * e1000_read_mac_addr_80003es2lan - Read device MAC address * @hw: pointer to the HW structure **/ @@ -1380,44 +1492,42 @@ static void e1000_power_down_phy_copper_ **/ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) { - volatile u32 temp; - DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan"); e1000_clear_hw_cntrs_base_generic(hw); - temp = E1000_READ_REG(hw, E1000_PRC64); - temp = E1000_READ_REG(hw, E1000_PRC127); - temp = E1000_READ_REG(hw, E1000_PRC255); - temp = E1000_READ_REG(hw, E1000_PRC511); - temp = E1000_READ_REG(hw, E1000_PRC1023); - temp = E1000_READ_REG(hw, E1000_PRC1522); - temp = E1000_READ_REG(hw, E1000_PTC64); - temp = E1000_READ_REG(hw, E1000_PTC127); - temp = E1000_READ_REG(hw, E1000_PTC255); - temp = E1000_READ_REG(hw, E1000_PTC511); - temp = E1000_READ_REG(hw, E1000_PTC1023); - temp = E1000_READ_REG(hw, E1000_PTC1522); - - temp = E1000_READ_REG(hw, E1000_ALGNERRC); - temp = E1000_READ_REG(hw, E1000_RXERRC); - temp = E1000_READ_REG(hw, E1000_TNCRS); - temp = E1000_READ_REG(hw, E1000_CEXTERR); - temp = E1000_READ_REG(hw, E1000_TSCTC); - temp = E1000_READ_REG(hw, E1000_TSCTFC); - - temp = E1000_READ_REG(hw, E1000_MGTPRC); - temp = E1000_READ_REG(hw, E1000_MGTPDC); - temp = E1000_READ_REG(hw, E1000_MGTPTC); - - temp = E1000_READ_REG(hw, E1000_IAC); - temp = E1000_READ_REG(hw, E1000_ICRXOC); - - temp = E1000_READ_REG(hw, E1000_ICRXPTC); - temp = E1000_READ_REG(hw, E1000_ICRXATC); - temp = E1000_READ_REG(hw, E1000_ICTXPTC); - temp = E1000_READ_REG(hw, E1000_ICTXATC); - temp = E1000_READ_REG(hw, E1000_ICTXQEC); - temp = E1000_READ_REG(hw, E1000_ICTXQMTC); - temp = E1000_READ_REG(hw, E1000_ICRXDMTC); + E1000_READ_REG(hw, E1000_PRC64); + E1000_READ_REG(hw, E1000_PRC127); + E1000_READ_REG(hw, E1000_PRC255); + E1000_READ_REG(hw, E1000_PRC511); + E1000_READ_REG(hw, E1000_PRC1023); + E1000_READ_REG(hw, E1000_PRC1522); + E1000_READ_REG(hw, E1000_PTC64); + E1000_READ_REG(hw, E1000_PTC127); + E1000_READ_REG(hw, E1000_PTC255); + E1000_READ_REG(hw, E1000_PTC511); + E1000_READ_REG(hw, E1000_PTC1023); + E1000_READ_REG(hw, E1000_PTC1522); + + E1000_READ_REG(hw, E1000_ALGNERRC); + E1000_READ_REG(hw, E1000_RXERRC); + E1000_READ_REG(hw, E1000_TNCRS); + E1000_READ_REG(hw, E1000_CEXTERR); + E1000_READ_REG(hw, E1000_TSCTC); + E1000_READ_REG(hw, E1000_TSCTFC); + + E1000_READ_REG(hw, E1000_MGTPRC); + E1000_READ_REG(hw, E1000_MGTPDC); + E1000_READ_REG(hw, E1000_MGTPTC); + + E1000_READ_REG(hw, E1000_IAC); + E1000_READ_REG(hw, E1000_ICRXOC); + + E1000_READ_REG(hw, E1000_ICRXPTC); + E1000_READ_REG(hw, E1000_ICRXATC); + E1000_READ_REG(hw, E1000_ICTXPTC); + E1000_READ_REG(hw, E1000_ICTXATC); + E1000_READ_REG(hw, E1000_ICTXQEC); + E1000_READ_REG(hw, E1000_ICTXQMTC); + E1000_READ_REG(hw, E1000_ICRXDMTC); } Modified: head/sys/dev/e1000/e1000_82540.c ============================================================================== --- head/sys/dev/e1000/e1000_82540.c Wed Nov 26 23:41:18 2008 (r185352) +++ head/sys/dev/e1000/e1000_82540.c Wed Nov 26 23:57:23 2008 (r185353) @@ -32,11 +32,15 @@ ******************************************************************************/ /*$FreeBSD$*/ -/* e1000_82540 - * e1000_82545 - * e1000_82546 - * e1000_82545_rev_3 - * e1000_82546_rev_3 +/* + * 82540EM Gigabit Ethernet Controller + * 82540EP Gigabit Ethernet Controller + * 82545EM Gigabit Ethernet Controller (Copper) + * 82545EM Gigabit Ethernet Controller (Fiber) + * 82545GM Gigabit Ethernet Controller + * 82546EB Gigabit Ethernet Controller (Copper) + * 82546EB Gigabit Ethernet Controller (Fiber) + * 82546GB Gigabit Ethernet Controller */ #include "e1000_api.h" @@ -57,8 +61,6 @@ static void e1000_power_down_phy_copper_ /** * e1000_init_phy_params_82540 - Init PHY func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_phy_params_82540(struct e1000_hw *hw) { @@ -110,8 +112,6 @@ out: /** * e1000_init_nvm_params_82540 - Init NVM func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) { @@ -153,8 +153,6 @@ static s32 e1000_init_nvm_params_82540(s /** * e1000_init_mac_params_82540 - Init MAC func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_mac_params_82540(struct e1000_hw *hw) { @@ -189,6 +187,8 @@ static s32 e1000_init_mac_params_82540(s /* bus type/speed/width */ mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; + /* function id */ + mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci; /* reset */ mac->ops.reset_hw = e1000_reset_hw_82540; /* hw initialization */ @@ -247,8 +247,7 @@ out: * e1000_init_function_pointers_82540 - Init func ptrs. * @hw: pointer to the HW structure * - * The only function explicitly called by the api module to initialize - * all function pointers and parameters. + * Called to initialize all function pointers and parameters. **/ void e1000_init_function_pointers_82540(struct e1000_hw *hw) { @@ -263,8 +262,7 @@ void e1000_init_function_pointers_82540( * e1000_reset_hw_82540 - Reset hardware * @hw: pointer to the HW structure * - * This resets the hardware into a known state. This is a - * function pointer entry point called by the api module. + * This resets the hardware into a known state. **/ static s32 e1000_reset_hw_82540(struct e1000_hw *hw) { @@ -322,8 +320,7 @@ static s32 e1000_reset_hw_82540(struct e * e1000_init_hw_82540 - Initialize hardware * @hw: pointer to the HW structure * - * This inits the hardware readying it for operation. This is a - * function pointer entry point called by the api module. + * This inits the hardware readying it for operation. **/ static s32 e1000_init_hw_82540(struct e1000_hw *hw) { @@ -406,8 +403,7 @@ static s32 e1000_init_hw_82540(struct e1 * Calls the appropriate function to configure the link for auto-neg or forced * speed and duplex. Then we check for link, once link is established calls * to configure collision distance and flow control are called. If link is - * not established, we return -E1000_ERR_PHY (-2). This is a function - * pointer entry point called by the api module. + * not established, we return -E1000_ERR_PHY (-2). **/ static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) { @@ -454,8 +450,7 @@ out: * Set the output amplitude to the value in the EEPROM and adjust the VCO * speed to improve Bit Error Rate (BER) performance. Configures collision * distance and flow control for fiber and serdes links. Upon successful - * setup, poll for link. This is a function pointer entry point called by - * the api module. + * setup, poll for link. **/ static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) { @@ -650,34 +645,32 @@ static void e1000_power_down_phy_copper_ **/ static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw) { - volatile u32 temp; - DEBUGFUNC("e1000_clear_hw_cntrs_82540"); e1000_clear_hw_cntrs_base_generic(hw); - temp = E1000_READ_REG(hw, E1000_PRC64); - temp = E1000_READ_REG(hw, E1000_PRC127); - temp = E1000_READ_REG(hw, E1000_PRC255); - temp = E1000_READ_REG(hw, E1000_PRC511); - temp = E1000_READ_REG(hw, E1000_PRC1023); - temp = E1000_READ_REG(hw, E1000_PRC1522); - temp = E1000_READ_REG(hw, E1000_PTC64); - temp = E1000_READ_REG(hw, E1000_PTC127); - temp = E1000_READ_REG(hw, E1000_PTC255); - temp = E1000_READ_REG(hw, E1000_PTC511); - temp = E1000_READ_REG(hw, E1000_PTC1023); - temp = E1000_READ_REG(hw, E1000_PTC1522); - - temp = E1000_READ_REG(hw, E1000_ALGNERRC); - temp = E1000_READ_REG(hw, E1000_RXERRC); - temp = E1000_READ_REG(hw, E1000_TNCRS); - temp = E1000_READ_REG(hw, E1000_CEXTERR); - temp = E1000_READ_REG(hw, E1000_TSCTC); - temp = E1000_READ_REG(hw, E1000_TSCTFC); - - temp = E1000_READ_REG(hw, E1000_MGTPRC); - temp = E1000_READ_REG(hw, E1000_MGTPDC); - temp = E1000_READ_REG(hw, E1000_MGTPTC); + E1000_READ_REG(hw, E1000_PRC64); + E1000_READ_REG(hw, E1000_PRC127); + E1000_READ_REG(hw, E1000_PRC255); + E1000_READ_REG(hw, E1000_PRC511); + E1000_READ_REG(hw, E1000_PRC1023); + E1000_READ_REG(hw, E1000_PRC1522); + E1000_READ_REG(hw, E1000_PTC64); + E1000_READ_REG(hw, E1000_PTC127); + E1000_READ_REG(hw, E1000_PTC255); + E1000_READ_REG(hw, E1000_PTC511); + E1000_READ_REG(hw, E1000_PTC1023); + E1000_READ_REG(hw, E1000_PTC1522); + + E1000_READ_REG(hw, E1000_ALGNERRC); + E1000_READ_REG(hw, E1000_RXERRC); + E1000_READ_REG(hw, E1000_TNCRS); + E1000_READ_REG(hw, E1000_CEXTERR); + E1000_READ_REG(hw, E1000_TSCTC); + E1000_READ_REG(hw, E1000_TSCTFC); + + E1000_READ_REG(hw, E1000_MGTPRC); + E1000_READ_REG(hw, E1000_MGTPDC); + E1000_READ_REG(hw, E1000_MGTPTC); } Modified: head/sys/dev/e1000/e1000_82541.c ============================================================================== --- head/sys/dev/e1000/e1000_82541.c Wed Nov 26 23:41:18 2008 (r185352) +++ head/sys/dev/e1000/e1000_82541.c Wed Nov 26 23:57:23 2008 (r185353) @@ -32,10 +32,13 @@ ******************************************************************************/ /*$FreeBSD$*/ -/* e1000_82541 - * e1000_82547 - * e1000_82541_rev_2 - * e1000_82547_rev_2 +/* + * 82541EI Gigabit Ethernet Controller + * 82541ER Gigabit Ethernet Controller + * 82541GI Gigabit Ethernet Controller + * 82541PI Gigabit Ethernet Controller + * 82547EI Gigabit Ethernet Controller + * 82547GI Gigabit Ethernet Controller */ #include "e1000_api.h" @@ -74,18 +77,9 @@ static const u16 e1000_igp_cable_length_ (sizeof(e1000_igp_cable_length_table) / \ sizeof(e1000_igp_cable_length_table[0])) -struct e1000_dev_spec_82541 { - enum e1000_dsp_config dsp_config; - enum e1000_ffe_config ffe_config; - u16 spd_default; - bool phy_init_script; -}; - /** * e1000_init_phy_params_82541 - Init PHY func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_phy_params_82541(struct e1000_hw *hw) { @@ -129,8 +123,6 @@ out: /** * e1000_init_nvm_params_82541 - Init NVM func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) { @@ -227,13 +219,10 @@ out: /** * e1000_init_mac_params_82541 - Init MAC func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; DEBUGFUNC("e1000_init_mac_params_82541"); @@ -250,6 +239,8 @@ static s32 e1000_init_mac_params_82541(s /* bus type/speed/width */ mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; + /* function id */ + mac->ops.set_lan_id = e1000_set_lan_id_single_port; /* reset */ mac->ops.reset_hw = e1000_reset_hw_82541; /* hw initialization */ @@ -277,25 +268,17 @@ static s32 e1000_init_mac_params_82541(s /* turn on/off LED */ mac->ops.led_on = e1000_led_on_generic; mac->ops.led_off = e1000_led_off_generic; - /* remove device */ - mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82541; - hw->dev_spec_size = sizeof(struct e1000_dev_spec_82541); - - /* Device-specific structure allocation */ - ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size); - - return ret_val; + return E1000_SUCCESS; } /** * e1000_init_function_pointers_82541 - Init func ptrs. * @hw: pointer to the HW structure * - * The only function explicitly called by the api module to initialize - * all function pointers and parameters. + * Called to initialize all function pointers and parameters. **/ void e1000_init_function_pointers_82541(struct e1000_hw *hw) { @@ -310,8 +293,7 @@ void e1000_init_function_pointers_82541( * e1000_reset_hw_82541 - Reset hardware * @hw: pointer to the HW structure * - * This resets the hardware into a known state. This is a - * function pointer entry point called by the api module. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***