Date: Wed, 24 Jun 2009 17:41:29 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r194865 - in head/sys: dev/e1000 modules/igb Message-ID: <200906241741.n5OHfTaw022417@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Wed Jun 24 17:41:29 2009 New Revision: 194865 URL: http://svn.freebsd.org/changeset/base/194865 Log: Updates for both the em and igb drivers, add support for multiqueue tx, shared code updates, new device support, and some bug fixes. Modified: head/sys/dev/e1000/e1000_82540.c head/sys/dev/e1000/e1000_82541.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_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_osdep.c 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 head/sys/dev/e1000/if_igb.h head/sys/modules/igb/Makefile Modified: head/sys/dev/e1000/e1000_82540.c ============================================================================== --- head/sys/dev/e1000/e1000_82540.c Wed Jun 24 17:31:37 2009 (r194864) +++ head/sys/dev/e1000/e1000_82540.c Wed Jun 24 17:41:29 2009 (r194865) @@ -57,6 +57,7 @@ static s32 e1000_set_vco_speed_82540(st static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw); static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82540(struct e1000_hw *hw); /** * e1000_init_phy_params_82540 - Init PHY func ptrs. @@ -229,6 +230,8 @@ static s32 e1000_init_mac_params_82540(s mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ mac->ops.mta_set = e1000_mta_set_generic; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82540; /* ID LED init */ mac->ops.id_led_init = e1000_id_led_init_generic; /* setup LED */ @@ -676,3 +679,45 @@ static void e1000_clear_hw_cntrs_82540(s E1000_READ_REG(hw, E1000_MGTPTC); } +/** + * e1000_read_mac_addr_82540 - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + * Since devices with two ports use the same EEPROM, we increment the + * last bit in the MAC address for the second port. + * + * This version is being used over generic because of customer issues + * with VmWare and Virtual Box when using generic. It seems in + * the emulated 82545, RAR[0] does NOT have a valid address after a + * reset, this older method works and using this breaks nothing for + * these legacy adapters. + **/ +s32 e1000_read_mac_addr_82540(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_data, i; + + DEBUGFUNC("e1000_read_mac_addr"); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = i >> 1; + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); + hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); + } + + /* Flip last bit of mac address if we're on second port */ + if (hw->bus.func == E1000_FUNC_1) + hw->mac.perm_addr[5] ^= 1; + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + +out: + return ret_val; +} Modified: head/sys/dev/e1000/e1000_82541.c ============================================================================== --- head/sys/dev/e1000/e1000_82541.c Wed Jun 24 17:31:37 2009 (r194864) +++ head/sys/dev/e1000/e1000_82541.c Wed Jun 24 17:41:29 2009 (r194865) @@ -377,6 +377,7 @@ static s32 e1000_reset_hw_82541(struct e static s32 e1000_init_hw_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; u32 i, txdctl; s32 ret_val; @@ -388,6 +389,13 @@ static s32 e1000_init_hw_82541(struct e1 DEBUGOUT("Error initializing identification LED\n"); /* This is not fatal and we should not stop init due to this */ } + + /* Storing the Speed Power Down value for later use */ + ret_val = hw->phy.ops.read_reg(hw, + IGP01E1000_GMII_FIFO, + &dev_spec->spd_default); + if (ret_val) + goto out; /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); @@ -425,6 +433,7 @@ static s32 e1000_init_hw_82541(struct e1 */ e1000_clear_hw_cntrs_82541(hw); +out: return ret_val; } Modified: head/sys/dev/e1000/e1000_82571.c ============================================================================== --- head/sys/dev/e1000/e1000_82571.c Wed Jun 24 17:31:37 2009 (r194864) +++ head/sys/dev/e1000/e1000_82571.c Wed Jun 24 17:41:29 2009 (r194865) @@ -47,6 +47,7 @@ * 82573L Gigabit Ethernet Controller * 82574L Gigabit Network Connection * 82574L Gigabit Network Connection + * 82583V Gigabit Network Connection */ #include "e1000_api.h" @@ -154,6 +155,7 @@ static s32 e1000_init_phy_params_82571(s goto out; } break; + case e1000_82583: case e1000_82574: phy->type = e1000_phy_bm; phy->ops.get_cfg_done = e1000_get_cfg_done_generic; @@ -215,6 +217,7 @@ static s32 e1000_init_nvm_params_82571(s switch (hw->mac.type) { case e1000_82573: case e1000_82574: + case e1000_82583: if (((eecd >> 15) & 0x3) == 0x3) { nvm->type = e1000_nvm_flash_hw; nvm->word_size = 2048; @@ -264,6 +267,9 @@ static s32 e1000_init_mac_params_82571(s { struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; + u32 swsm = 0; + u32 swsm2 = 0; + bool force_clear_smbi = FALSE; DEBUGFUNC("e1000_init_mac_params_82571"); @@ -304,6 +310,7 @@ static s32 e1000_init_mac_params_82571(s switch (hw->mac.type) { case e1000_82573: case e1000_82574: + case e1000_82583: mac->ops.set_lan_id = e1000_set_lan_id_single_port; break; default: @@ -339,6 +346,7 @@ static s32 e1000_init_mac_params_82571(s /* check management mode */ switch (hw->mac.type) { case e1000_82574: + case e1000_82583: mac->ops.check_mng_mode = e1000_check_mng_mode_82574; break; default: @@ -366,6 +374,7 @@ static s32 e1000_init_mac_params_82571(s /* turn on/off LED */ switch (hw->mac.type) { case e1000_82574: + case e1000_82583: mac->ops.led_on = e1000_led_on_82574; break; default: @@ -381,6 +390,50 @@ static s32 e1000_init_mac_params_82571(s ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; + /* + * Ensure that the inter-port SWSM.SMBI lock bit is clear before + * first NVM or PHY acess. This should be done for single-port + * devices, and for one port only on dual-port devices so that + * for those devices we can still use the SMBI lock to synchronize + * inter-port accesses to the PHY & NVM. + */ + switch (hw->mac.type) { + case e1000_82571: + case e1000_82572: + swsm2 = E1000_READ_REG(hw, E1000_SWSM2); + + if (!(swsm2 & E1000_SWSM2_LOCK)) { + /* Only do this for the first interface on this card */ + E1000_WRITE_REG(hw, E1000_SWSM2, + swsm2 | E1000_SWSM2_LOCK); + force_clear_smbi = TRUE; + } else + force_clear_smbi = FALSE; + break; + default: + force_clear_smbi = TRUE; + break; + } + + if (force_clear_smbi) { + /* Make sure SWSM.SMBI is clear */ + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (swsm & E1000_SWSM_SMBI) { + /* This bit should not be set on a first interface, and + * indicates that the bootagent or EFI code has + * improperly left this bit enabled + */ + DEBUGOUT("Please update your 82571 Bootagent\n"); + } + E1000_WRITE_REG(hw, E1000_SWSM, swsm & ~E1000_SWSM_SMBI); + } + + /* + * Initialze device specific counter of SMBI acquisition + * timeouts. + */ + hw->dev_spec._82571.smb_counter = 0; + out: return ret_val; } @@ -430,6 +483,7 @@ static s32 e1000_get_phy_id_82571(struct ret_val = e1000_get_phy_id(hw); break; case e1000_82574: + case e1000_82583: ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); if (ret_val) goto out; @@ -458,17 +512,43 @@ out: * * Acquire the HW semaphore to access the PHY or NVM **/ -static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) +s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; s32 ret_val = E1000_SUCCESS; - s32 timeout = hw->nvm.word_size + 1; + s32 sw_timeout = hw->nvm.word_size + 1; + s32 fw_timeout = hw->nvm.word_size + 1; s32 i = 0; DEBUGFUNC("e1000_get_hw_semaphore_82571"); + /* + * If we have timedout 3 times on trying to acquire + * the inter-port SMBI semaphore, there is old code + * operating on the other port, and it is not + * releasing SMBI. Modify the number of times that + * we try for the semaphore to interwork with this + * older code. + */ + if (hw->dev_spec._82571.smb_counter > 2) + sw_timeout = 1; + + /* Get the SW semaphore */ + while (i < sw_timeout) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + usec_delay(50); + i++; + } + + if (i == sw_timeout) { + DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); + hw->dev_spec._82571.smb_counter++; + } /* Get the FW semaphore. */ - for (i = 0; i < timeout; i++) { + for (i = 0; i < fw_timeout; i++) { swsm = E1000_READ_REG(hw, E1000_SWSM); E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); @@ -479,9 +559,9 @@ static s32 e1000_get_hw_semaphore_82571( usec_delay(50); } - if (i == timeout) { + if (i == fw_timeout) { /* Release semaphores */ - e1000_put_hw_semaphore_generic(hw); + e1000_put_hw_semaphore_82571(hw); DEBUGOUT("Driver can't access the NVM\n"); ret_val = -E1000_ERR_NVM; goto out; @@ -497,15 +577,15 @@ out: * * Release hardware semaphore used to access the PHY or NVM **/ -static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) +void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; - DEBUGFUNC("e1000_put_hw_semaphore_82571"); + DEBUGFUNC("e1000_put_hw_semaphore_generic"); swsm = E1000_READ_REG(hw, E1000_SWSM); - swsm &= ~E1000_SWSM_SWESMBI; + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); E1000_WRITE_REG(hw, E1000_SWSM, swsm); } @@ -531,6 +611,7 @@ static s32 e1000_acquire_nvm_82571(struc switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: break; default: @@ -581,6 +662,7 @@ static s32 e1000_write_nvm_82571(struct switch (hw->mac.type) { case e1000_82573: case e1000_82574: + case e1000_82583: ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); break; case e1000_82571: @@ -885,6 +967,7 @@ static s32 e1000_reset_hw_82571(struct e */ switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; @@ -932,6 +1015,7 @@ static s32 e1000_reset_hw_82571(struct e switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: msec_delay(25); break; @@ -1014,6 +1098,7 @@ static s32 e1000_init_hw_82571(struct e1 /* ...for both queues. */ switch (mac->type) { case e1000_82574: + case e1000_82583: case e1000_82573: e1000_enable_tx_pkt_filtering_generic(hw); reg_data = E1000_READ_REG(hw, E1000_GCR); @@ -1096,6 +1181,7 @@ static void e1000_initialize_hw_bits_825 switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: reg = E1000_READ_REG(hw, E1000_CTRL); reg &= ~(1 << 29); @@ -1108,6 +1194,7 @@ static void e1000_initialize_hw_bits_825 /* Extended Device Control */ switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: reg = E1000_READ_REG(hw, E1000_CTRL_EXT); reg &= ~(1 << 23); @@ -1141,6 +1228,7 @@ static void e1000_initialize_hw_bits_825 switch (hw->mac.type) { case e1000_82574: + case e1000_82583: reg = E1000_READ_REG(hw, E1000_GCR); reg |= (1 << 22); E1000_WRITE_REG(hw, E1000_GCR, reg); @@ -1180,6 +1268,7 @@ static void e1000_clear_vfta_82571(struc switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: if (hw->mng_cookie.vlan_id != 0) { /* @@ -1281,6 +1370,7 @@ static s32 e1000_setup_link_82571(struct */ switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: if (hw->fc.requested_mode == e1000_fc_default) hw->fc.requested_mode = e1000_fc_full; @@ -1301,7 +1391,7 @@ static s32 e1000_setup_link_82571(struct **/ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) { - u32 ctrl, led_ctrl; + u32 ctrl; s32 ret_val; DEBUGFUNC("e1000_setup_copper_link_82571"); @@ -1318,11 +1408,6 @@ static s32 e1000_setup_copper_link_82571 break; case e1000_phy_igp_2: 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; @@ -1372,8 +1457,20 @@ static s32 e1000_setup_fiber_serdes_link * e1000_check_for_serdes_link_82571 - Check for link (Serdes) * @hw: pointer to the HW structure * - * Checks for link up on the hardware. If link is not up and we have - * a signal, then we need to force link up. + * Reports the link state as up or down. + * + * If autonegotiation is supported by the link partner, the link state is + * determined by the result of autongotiation. This is the most likely case. + * If autonegotiation is not supported by the link partner, and the link + * has a valid signal, force the link up. + * + * The link state is represented internally here by 4 states: + * + * 1) down + * 2) autoneg_progress + * 3) autoneg_complete (the link sucessfully autonegotiated) + * 4) forced_up (the link has been forced up, it did not autonegotiate) + * **/ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) { @@ -1401,6 +1498,7 @@ s32 e1000_check_for_serdes_link_82571(st */ mac->serdes_link_state = e1000_serdes_link_autoneg_progress; + mac->serdes_has_link = FALSE; DEBUGOUT("AN_UP -> AN_PROG\n"); } break; @@ -1419,28 +1517,35 @@ s32 e1000_check_for_serdes_link_82571(st (ctrl & ~E1000_CTRL_SLU)); mac->serdes_link_state = e1000_serdes_link_autoneg_progress; + mac->serdes_has_link = FALSE; DEBUGOUT("FORCED_UP -> AN_PROG\n"); } break; case e1000_serdes_link_autoneg_progress: - /* - * If the LU bit is set in the STATUS register, - * autoneg has completed sucessfully. If not, - * try foring the link because the far end may be - * available but not capable of autonegotiation. - */ - if (status & E1000_STATUS_LU) { - mac->serdes_link_state = - e1000_serdes_link_autoneg_complete; - DEBUGOUT("AN_PROG -> AN_UP\n"); + if (rxcw & E1000_RXCW_C) { + /* We received /C/ ordered sets, meaning the + * link partner has autonegotiated, and we can + * trust the Link Up (LU) status bit + */ + if (status & E1000_STATUS_LU) { + mac->serdes_link_state = + e1000_serdes_link_autoneg_complete; + DEBUGOUT("AN_PROG -> AN_UP\n"); + mac->serdes_has_link = TRUE; + } else { + /* Autoneg completed, but failed */ + mac->serdes_link_state = + e1000_serdes_link_down; + DEBUGOUT("AN_PROG -> DOWN\n"); + } } else { - /* - * Disable autoneg, force link up and - * full duplex, and change state to forced + /* The link partner did not autoneg. + * Force link up and full duplex, and change + * state to forced. */ E1000_WRITE_REG(hw, E1000_TXCW, - (mac->txcw & ~E1000_TXCW_ANE)); + (mac->txcw & ~E1000_TXCW_ANE)); ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); @@ -1452,10 +1557,10 @@ s32 e1000_check_for_serdes_link_82571(st break; } mac->serdes_link_state = - e1000_serdes_link_forced_up; + e1000_serdes_link_forced_up; + mac->serdes_has_link = TRUE; DEBUGOUT("AN_PROG -> FORCED_UP\n"); } - mac->serdes_has_link = TRUE; break; case e1000_serdes_link_down: @@ -1517,6 +1622,7 @@ static s32 e1000_valid_led_default_82571 switch (hw->mac.type) { case e1000_82574: + case e1000_82583: case e1000_82573: if(*data == ID_LED_RESERVED_F746) *data = ID_LED_DEFAULT_82573; Modified: head/sys/dev/e1000/e1000_82575.c ============================================================================== --- head/sys/dev/e1000/e1000_82575.c Wed Jun 24 17:31:37 2009 (r194864) +++ head/sys/dev/e1000/e1000_82575.c Wed Jun 24 17:41:29 2009 (r194865) @@ -38,6 +38,7 @@ * 82575GB Gigabit Network Connection * 82575GB Gigabit Network Connection * 82576 Gigabit Network Connection + * 82576 Quad Port Gigabit Mezzanine Adapter */ #include "e1000_api.h" @@ -77,6 +78,7 @@ static s32 e1000_reset_init_script_8257 static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw); 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. @@ -326,11 +328,12 @@ void e1000_init_function_pointers_82575( **/ 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); } @@ -343,11 +346,13 @@ static s32 e1000_acquire_phy_82575(struc **/ 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); } @@ -785,9 +790,8 @@ static s32 e1000_get_cfg_done_82575(stru 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) { if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) break; @@ -937,13 +941,13 @@ void e1000_shutdown_fiber_serdes_link_82 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 @@ -970,250 +974,42 @@ void e1000_shutdown_fiber_serdes_link_82 } /** - * e1000_vmdq_loopback_enable_pf- Enables VM to VM queue loopback replication - * @hw: pointer to the HW structure - **/ -void e1000_vmdq_loopback_enable_pf(struct e1000_hw *hw) -{ - u32 reg; - - reg = E1000_READ_REG(hw, E1000_DTXSWC); - reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; - E1000_WRITE_REG(hw, E1000_DTXSWC, reg); -} - -/** - * e1000_vmdq_loopback_disable_pf - Disable VM to VM queue loopbk replication + * 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_loopback_disable_pf(struct e1000_hw *hw) +void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) { u32 reg; reg = E1000_READ_REG(hw, E1000_DTXSWC); - reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN); + if (enable) + reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN; + else + reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN); E1000_WRITE_REG(hw, E1000_DTXSWC, reg); } /** - * e1000_vmdq_replication_enable_pf - Enable replication of brdcst & multicst - * @hw: pointer to the HW structure - * - * Enables replication of broadcast and multicast packets from the network - * to VM's which have their respective broadcast and multicast accept - * bits set in the VM Offload Register. This gives the PF driver per - * VM granularity control over which VM's get replicated broadcast traffic. - **/ -void e1000_vmdq_replication_enable_pf(struct e1000_hw *hw, u32 enables) -{ - u32 reg; - u32 i; - - for (i = 0; i < MAX_NUM_VFS; i++) { - if (enables & (1 << i)) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - reg |= (E1000_VMOLR_AUPE | - E1000_VMOLR_BAM | - E1000_VMOLR_MPME); - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - } - - reg = E1000_READ_REG(hw, E1000_VT_CTL); - reg |= E1000_VT_CTL_VM_REPL_EN; - E1000_WRITE_REG(hw, E1000_VT_CTL, reg); -} - -/** - * e1000_vmdq_replication_disable_pf - Disable replication of brdcst & multicst + * e1000_vmdq_set_replication_pf - enable or disable vmdq replication * @hw: pointer to the HW structure + * @enable: state to enter, either enabled or disabled * - * Disables replication of broadcast and multicast packets to the VM's. + * enables/disables replication of packets across multiple pools **/ -void e1000_vmdq_replication_disable_pf(struct e1000_hw *hw) +void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) { u32 reg; reg = E1000_READ_REG(hw, E1000_VT_CTL); - reg &= ~(E1000_VT_CTL_VM_REPL_EN); - E1000_WRITE_REG(hw, E1000_VT_CTL, reg); -} - -/** - * e1000_vmdq_enable_replication_mode_pf - Enables replication mode in the device - * @hw: pointer to the HW structure - **/ -void e1000_vmdq_enable_replication_mode_pf(struct e1000_hw *hw) -{ - u32 reg; - - reg = E1000_READ_REG(hw, E1000_VT_CTL); - reg |= E1000_VT_CTL_VM_REPL_EN; - E1000_WRITE_REG(hw, E1000_VT_CTL, reg); -} - -/** - * e1000_vmdq_broadcast_replication_enable_pf - Enable replication of brdcst - * @hw: pointer to the HW structure - * @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Enables replication of broadcast packets from the network - * to VM's which have their respective broadcast accept - * bits set in the VM Offload Register. This gives the PF driver per - * VM granularity control over which VM's get replicated broadcast traffic. - **/ -void e1000_vmdq_broadcast_replication_enable_pf(struct e1000_hw *hw, - u32 enables) -{ - u32 reg; - u32 i; - - for (i = 0; i < MAX_NUM_VFS; i++) { - if ((enables == ALL_QUEUES) || (enables & (1 << i))) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - reg |= E1000_VMOLR_BAM; - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - } -} - -/** - * e1000_vmdq_broadcast_replication_disable_pf - Disable replication - * of broadcast packets - * @hw: pointer to the HW structure - * @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Disables replication of broadcast packets for specific pools. - * If bam/mpe is disabled on all pools then replication mode is - * turned off. - **/ -void e1000_vmdq_broadcast_replication_disable_pf(struct e1000_hw *hw, - u32 disables) -{ - u32 reg; - u32 i; - u32 oneenabled = 0; - - for (i = 0; i < MAX_NUM_VFS; i++) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - if ((disables == ALL_QUEUES) || (disables & (1 << i))) { - reg &= ~(E1000_VMOLR_BAM); - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - if (!oneenabled && (reg & (E1000_VMOLR_AUPE | - E1000_VMOLR_BAM | - E1000_VMOLR_MPME))) - oneenabled = 1; - } - if (!oneenabled) { - 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_vmdq_multicast_promiscuous_enable_pf - Enable promiscuous reception - * @hw: pointer to the HW structure - * @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Enables promiscuous reception of multicast packets from the network - * to VM's which have their respective multicast promiscuous mode enable - * bits set in the VM Offload Register. This gives the PF driver per - * VM granularity control over which VM's get all multicast traffic. - **/ -void e1000_vmdq_multicast_promiscuous_enable_pf(struct e1000_hw *hw, - u32 enables) -{ - u32 reg; - u32 i; - - for (i = 0; i < MAX_NUM_VFS; i++) { - if ((enables == ALL_QUEUES) || (enables & (1 << i))) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - reg |= E1000_VMOLR_MPME; - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - } -} - -/** - * e1000_vmdq_multicast_promiscuous_disable_pf - Disable promiscuous - * reception of multicast packets - * @hw: pointer to the HW structure - * @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Disables promiscuous reception of multicast packets for specific pools. - * If bam/mpe is disabled on all pools then replication mode is - * turned off. - **/ -void e1000_vmdq_multicast_promiscuous_disable_pf(struct e1000_hw *hw, - u32 disables) -{ - u32 reg; - u32 i; - u32 oneenabled = 0; - - for (i = 0; i < MAX_NUM_VFS; i++) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - if ((disables == ALL_QUEUES) || (disables & (1 << i))) { - reg &= ~(E1000_VMOLR_MPME); - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - if (!oneenabled && (reg & (E1000_VMOLR_AUPE | - E1000_VMOLR_BAM | - E1000_VMOLR_MPME))) - oneenabled = 1; - } - if (!oneenabled) { - reg = E1000_READ_REG(hw, E1000_VT_CTL); - reg &= ~(E1000_VT_CTL_VM_REPL_EN); - E1000_WRITE_REG(hw, E1000_VT_CTL, reg); - } -} - -/** - * e1000_vmdq_aupe_enable_pf - Enable acceptance of untagged packets - * @hw: pointer to the HW structure - * @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Enables acceptance of packets from the network which do not have - * a VLAN tag but match the exact MAC filter of a given VM. - **/ -void e1000_vmdq_aupe_enable_pf(struct e1000_hw *hw, u32 enables) -{ - u32 reg; - u32 i; - - for (i = 0; i < MAX_NUM_VFS; i++) { - if ((enables == ALL_QUEUES) || (enables & (1 << i))) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - reg |= E1000_VMOLR_AUPE; - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - } -} - -/** - * e1000_vmdq_aupe_disable_pf - Disable acceptance of untagged packets - * @hw: pointer to the HW structure - * @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools. - * - * Disables acceptance of packets from the network which do not have - * a VLAN tag but match the exact MAC filter of a given VM. - **/ -void e1000_vmdq_aupe_disable_pf(struct e1000_hw *hw, u32 disables) -{ - u32 reg; - u32 i; - - for (i = 0; i < MAX_NUM_VFS; i++) { - if ((disables == ALL_QUEUES) || (disables & (1 << i))) { - reg = E1000_READ_REG(hw, E1000_VMOLR(i)); - reg &= ~E1000_VMOLR_AUPE; - E1000_WRITE_REG(hw, E1000_VMOLR(i), reg); - } - } + E1000_WRITE_REG(hw, E1000_VT_CTL, reg); } /** @@ -1238,6 +1034,12 @@ static s32 e1000_reset_hw_82575(struct e 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); @@ -1333,7 +1135,7 @@ static s32 e1000_init_hw_82575(struct e1 **/ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) { - u32 ctrl, led_ctrl; + u32 ctrl; s32 ret_val; bool link; @@ -1350,11 +1152,6 @@ static s32 e1000_setup_copper_link_82575 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; @@ -1433,15 +1230,14 @@ static s32 e1000_setup_fiber_serdes_link */ 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 */ if (hw->mac.type == e1000_82576) { reg = E1000_READ_REG(hw, E1000_CTRL_EXT); @@ -1514,7 +1310,6 @@ static s32 e1000_valid_led_default_82575 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; @@ -1605,12 +1400,6 @@ out: static bool 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; } @@ -1762,6 +1551,7 @@ static void e1000_clear_hw_cntrs_82575(s if (hw->phy.media_type == e1000_media_type_internal_serdes) E1000_READ_REG(hw, E1000_SCVPC); } + /** * e1000_rx_fifo_flush_82575 - Clean rx fifo after RX enable * @hw: pointer to the HW structure @@ -1836,3 +1626,54 @@ void e1000_rx_fifo_flush_82575(struct e1 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; +} + Modified: head/sys/dev/e1000/e1000_82575.h ============================================================================== --- head/sys/dev/e1000/e1000_82575.h Wed Jun 24 17:31:37 2009 (r194864) +++ head/sys/dev/e1000/e1000_82575.h Wed Jun 24 17:41:29 2009 (r194865) @@ -214,7 +214,7 @@ union e1000_adv_rx_desc { } 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 @@ -421,21 +421,11 @@ struct e1000_adv_tx_context_desc { #define E1000_IOVCTL 0x05BBC #define E1000_IOVCTL_REUSE_VFQ 0x00000001 +#define E1000_RPLOLR_STRVLAN 0x40000000 +#define E1000_RPLOLR_STRCRC 0x80000000 *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906241741.n5OHfTaw022417>